@@ -3,76 +3,136 @@ title: CSV
33description : How to define, write and query CSV data.
44---
55
6- ## Define Collection
6+ ## Single-file source
7+
8+ When you point a collection to a single CSV file (instead of a glob), Nuxt Content ** treats each data row as a separate item** in the collection.
9+
10+ - ** Define the collection** : set ` source ` to the path of a single ` .csv ` file.
11+ - ** Item generation** : each data row becomes an item with the row’s fields at the top level (no ` body ` array).
12+ - ** IDs** : item IDs are suffixed with ` #<rowNumber> ` , where ` #1 ` is the first data row after the header.
713
814``` ts [content.config.ts]
915import { defineCollection , defineContentConfig } from ' @nuxt/content'
1016import { z } from ' zod'
1117
1218export default defineContentConfig ({
1319 collections: {
14- authors : defineCollection ({
20+ people : defineCollection ({
1521 type: ' data' ,
16- source: ' authors/** .csv' ,
22+ source: ' org/people .csv' ,
1723 schema: z .object ({
1824 name: z .string (),
19- email: z .string (),
20- avatar: z .string ()
25+ email: z .string ().email ()
2126 })
2227 })
2328 }
2429})
30+ ```
31+
32+ ``` csv [content/org/people.csv]
33+ name,email
34+ Alice,alice@example.com
35+ Bob,bob@example.com
36+ ```
37+
38+ Each row produces its own item. For example, the first data row will have an ID ending with ` #1 ` and the second with ` #2 ` . You can query by any column:
39+
40+ ``` ts
41+ const { data : alice } = await useAsyncData (' alice' , () =>
42+ queryCollection (' people' )
43+ .where (' email' , ' =' , ' alice@example.com' )
44+ .first ()
45+ )
2546
47+ const { data : allPeople } = await useAsyncData (' all-people' , () =>
48+ queryCollection (' people' )
49+ .order (' name' , ' ASC' )
50+ .all ()
51+ )
2652```
2753
28- ## Create ` .csv ` files
54+ :: note
55+ - The header row is required and is not turned into an item.
56+ - With a single-file source, items contain row fields at the top level (no ` body ` ).
57+ - If you prefer treating each CSV file as a single item containing all rows in ` body ` , use a glob source like ` org/**.csv ` instead of a single file.
58+ :::
59+
60+ ## Multiple-files source
2961
30- Create author files in ` content/authors/ ` directory.
62+ If you uses ` */**.csv ` as source in configuration, Nuxt Content will treat them differently from single-file collections.
63+ ** Each file(not row) will be treated as an item** , rows will be parsed into ` body ` field in item object as an array.
64+
65+ ``` ts [content.config.ts]
66+ import { defineCollection , defineContentConfig } from ' @nuxt/content'
67+ import { z } from ' zod'
68+
69+ export default defineContentConfig ({
70+ collections: {
71+ charts: defineCollection ({
72+ type: ' data' ,
73+ source: ' charts/**.csv' ,
74+ schema: z .object ({
75+ // Body is important in CSV files, without body field you cannot access to data array
76+ body: z .array (z .object ({
77+ label: z .string (),
78+ value: z .number ()
79+ }))
80+ })
81+ })
82+ }
83+ })
84+
85+ ```
86+
87+ Create chart files in ` content/charts/ ` directory.
3188
3289:: code-group
33- ``` csv [users .csv]
34- id,name,email
35- 1,John Doe,john@example.com
36- 2,Jane Smith,jane@example.com
37- 3,Alice Johnson,alice@example.com
90+ ``` csv [content/charts/chart1 .csv]
91+ label,value
92+ A,100
93+ B,200
94+ C,300
3895```
3996
40- ``` csv [team.csv]
41- name,role,avatar
42- John Doe,Developer,https://avatars.githubusercontent.com/u/1?v=4
43- Jane Smith,Designer,https://avatars.githubusercontent.com/u/2?v=4
97+ ``` csv [content/charts/chart2.csv]
98+ label,value
99+ Foo,123
100+ Bar,456
101+ Baz,789
44102```
45103::
46104
47105:: warning
48106Each CSV file should have a header row that defines the column names, which will be used as object keys when parsed.
49107::
50108
51- ## Query Data
52-
53- Now we can query authors:
109+ Now we can query charts:
54110
55111``` vue
56112<script lang="ts" setup>
57- // Find a single author
58- const { data: author } = await useAsyncData('john-doe ', () => {
59- return queryCollection('authors ')
60- .where('name ', '=', 'John Doe ')
113+ // Find a single chart
114+ const { data: chart1 } = await useAsyncData('chart1 ', () => {
115+ return queryCollection('charts ')
116+ .where('id ', '=', 'charts/charts/chart1.csv ')
61117 .first()
62118})
63119
64- // Get all authors
65- const { data: authors } = await useAsyncData('authors ', () => {
66- return queryCollection('authors ')
67- .order('name ', 'ASC')
120+ // Get all charts
121+ const { data: charts } = await useAsyncData('charts ', () => {
122+ return queryCollection('charts ')
123+ .order('id ', 'ASC')
68124 .all()
69125})
126+
70127</script>
71128
72129<template>
73130 <ul>
74- <li v-for="author in authors" :key="author.id">
75- {{ author.name }} ({{ author.email }})
131+ <li v-for="chart in charts" :key="chart.id">
132+ <!-- CSV data are in `chart.body` as an array -->
133+ <p v-for="data in chart.body">
134+ {{ data.label }} - {{ data.value }}
135+ </p>
76136 </li>
77137 </ul>
78138</template>
0 commit comments