[{"data":1,"prerenderedAt":2801},["ShallowReactive",2],{"navigation":3,"/docs/advanced/fulltext-search":195,"ULASlAsXym":1658,"search-data":1671},[4,24,43,61,83,101,135,165],{"title":5,"path":6,"stem":7,"children":8,"icon":23},"Getting Started","/docs/getting-started","docs/1.getting-started/1.index",[9,11,15,19],{"title":10,"path":6,"stem":7},"Introduction",{"title":12,"path":13,"stem":14},"Installation","/docs/getting-started/installation","docs/1.getting-started/2.installation",{"title":16,"path":17,"stem":18},"Configuration","/docs/getting-started/configuration","docs/1.getting-started/3.configuration",{"title":20,"path":21,"stem":22},"Migration","/docs/getting-started/migration","docs/1.getting-started/4.migration","i-lucide-square-play",{"title":25,"icon":26,"path":27,"stem":28,"children":29,"page":42},"Collections","i-lucide-database","/docs/collections","docs/2.collections",[30,34,38],{"title":31,"path":32,"stem":33},"Define","/docs/collections/define","docs/2.collections/1.define",{"title":35,"path":36,"stem":37},"Types","/docs/collections/types","docs/2.collections/2.types",{"title":39,"path":40,"stem":41},"Sources","/docs/collections/sources","docs/2.collections/3.sources",false,{"title":44,"icon":45,"path":46,"stem":47,"children":48,"page":42},"Files","i-lucide-file","/docs/files","docs/3.files",[49,53,57],{"title":50,"path":51,"stem":52},"Markdown","/docs/files/markdown","docs/3.files/1.markdown",{"title":54,"path":55,"stem":56},"YAML","/docs/files/yaml","docs/3.files/2.yaml",{"title":58,"path":59,"stem":60},"JSON","/docs/files/json","docs/3.files/3.json",{"title":62,"icon":63,"path":64,"stem":65,"children":66,"page":42},"Query Utils","i-lucide-square-function","/docs/utils","docs/4.utils",[67,71,75,79],{"title":68,"path":69,"stem":70},"queryCollection","/docs/utils/query-collection","docs/4.utils/1.query-collection",{"title":72,"path":73,"stem":74},"queryCollectionNavigation","/docs/utils/query-collection-navigation","docs/4.utils/2.query-collection-navigation",{"title":76,"path":77,"stem":78},"queryCollectionItemSurroundings","/docs/utils/query-collection-item-surroundings","docs/4.utils/3.query-collection-item-surroundings",{"title":80,"path":81,"stem":82},"queryCollectionSearchSections","/docs/utils/query-collection-search-sections","docs/4.utils/4.query-collection-search-sections",{"title":84,"icon":85,"path":86,"stem":87,"children":88,"page":42},"Components","i-lucide-square-code","/docs/components","docs/5.components",[89,93,97],{"title":90,"path":91,"stem":92},"ContentRenderer","/docs/components/content-renderer","docs/5.components/0.content-renderer",{"title":94,"path":95,"stem":96},"Slot","/docs/components/slot","docs/5.components/1.slot",{"title":98,"path":99,"stem":100},"Prose Components","/docs/components/prose","docs/5.components/2.prose",{"title":102,"icon":103,"path":104,"stem":105,"children":106,"page":42},"Deploy","i-lucide-cloud-upload","/docs/deploy","docs/6.deploy",[107,111,115,119,123,127,131],{"title":108,"path":109,"stem":110},"Server","/docs/deploy/server","docs/6.deploy/1.server",{"title":112,"path":113,"stem":114},"Serverless","/docs/deploy/serverless","docs/6.deploy/2.serverless",{"title":116,"path":117,"stem":118},"NuxtHub","/docs/deploy/nuxthub","docs/6.deploy/3.nuxthub",{"title":120,"path":121,"stem":122},"Cloudflare Pages","/docs/deploy/cloudflare-pages","docs/6.deploy/4.cloudflare-pages",{"title":124,"path":125,"stem":126},"Vercel","/docs/deploy/vercel","docs/6.deploy/5.vercel",{"title":128,"path":129,"stem":130},"Docker","/docs/deploy/docker","docs/6.deploy/6.docker",{"title":132,"path":133,"stem":134},"Static","/docs/deploy/static","docs/6.deploy/7.static",{"title":136,"icon":137,"path":138,"stem":139,"children":140,"page":42},"Advanced","i-lucide-code-xml","/docs/advanced","docs/7.advanced",[141,145,149,153,157,161],{"title":142,"path":143,"stem":144},"Full-Text Search","/docs/advanced/fulltext-search","docs/7.advanced/1.fulltext-search",{"title":146,"path":147,"stem":148},"Raw Content","/docs/advanced/raw-content","docs/7.advanced/2.raw-content",{"title":150,"path":151,"stem":152},"SQL Storage","/docs/advanced/database","docs/7.advanced/3.database",{"title":154,"path":155,"stem":156},"Debugging tools","/docs/advanced/tools","docs/7.advanced/4.tools",{"title":158,"path":159,"stem":160},"Hooks","/docs/advanced/hooks","docs/7.advanced/5.hooks",{"title":162,"path":163,"stem":164},"Custom Source","/docs/advanced/custom-source","docs/7.advanced/6.custom-source",{"title":166,"icon":167,"path":168,"stem":169,"children":170,"page":42},"Studio","i-lucide-monitor","/docs/studio","docs/8.studio",[171,175,179,183,187,191],{"title":172,"path":173,"stem":174},"Setup","/docs/studio/setup","docs/8.studio/1.setup",{"title":176,"path":177,"stem":178},"Synchronization","/docs/studio/github","docs/8.studio/2.github",{"title":180,"path":181,"stem":182},"Content editors","/docs/studio/content","docs/8.studio/3.content",{"title":184,"path":185,"stem":186},"Medias","/docs/studio/medias","docs/8.studio/4.medias",{"title":188,"path":189,"stem":190},"App Config","/docs/studio/config","docs/8.studio/5.config",{"title":192,"path":193,"stem":194},"Local Debug","/docs/studio/debug","docs/8.studio/6.debug",{"page":196,"surround":1653},{"id":197,"title":142,"body":198,"description":1648,"extension":1649,"links":1650,"meta":1651,"navigation":424,"path":143,"seo":1652,"stem":144},"docs/docs/7.advanced/1.fulltext-search.md",{"type":199,"value":200,"toc":1643},"minimal",[201,231,236,246,253,562,566,571,1144,1148,1154,1639],[202,203,204,205,211,212,218,219,224,225,230],"p",{},"Content module exposes a handy utility ",[206,207,208],"a",{"href":81},[209,210,80],"code",{}," to break down content files into searchable sections. This is useful for implementing full-text search in your website. You can use the result of this utility in combination with ",[206,213,217],{"href":214,"rel":215},"https://ui.nuxt.com/pro/components/content-search",[216],"nofollow","Nuxt UI Content Search"," or other search libraries like ",[206,220,223],{"href":221,"rel":222},"https://fusejs.io/",[216],"Fuse.js",", ",[206,226,229],{"href":227,"rel":228},"https://lucaong.github.io/minisearch",[216],"minisearch",", etc.",[232,233,235],"h2",{"id":234},"nuxt-ui-pro","Nuxt UI Pro",[202,237,238,239,241,242,245],{},"Nuxt UI Pro provides a ready to use component for full-text search. You can use it by passing the result of ",[209,240,80],{}," to the ",[209,243,244],{},"files"," prop of the component.",[202,247,248,249,252],{},"Read more about ",[206,250,217],{"href":214,"rel":251},[216],".",[254,255,256,555],"code-group",{},[257,258,264],"pre",{"className":259,"code":260,"filename":261,"language":262,"meta":263,"style":263},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript setup lang=\"ts\">\nconst { data: navigation } = await useAsyncData('navigation', () => queryCollectionNavigation('docs'))\nconst { data: files } = await useAsyncData('search', () => queryCollectionSearchSections('docs'))\n\nconst searchTerm = ref('')\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CUContentSearch\n    v-model:search-term=\"searchTerm\"\n    :files=\"files\"\n    :navigation=\"navigation\"\n    :fuse=\"{ resultLimit: 42 }\"\n  />\n\u003C/template>\n","UContentSearchExample.vue","vue","",[209,265,266,301,369,419,426,447,457,462,472,481,497,511,525,540,546],{"__ignoreMap":263},[267,268,271,275,279,283,286,289,292,296,298],"span",{"class":269,"line":270},"line",1,[267,272,274],{"class":273},"s86vT","\u003C",[267,276,278],{"class":277},"sd2Uz","script",[267,280,282],{"class":281},"s50WR"," setup",[267,284,285],{"class":281}," lang",[267,287,288],{"class":273},"=",[267,290,291],{"class":273},"\"",[267,293,295],{"class":294},"sIEYB","ts",[267,297,291],{"class":273},[267,299,300],{"class":273},">\n",[267,302,304,307,310,313,316,320,323,326,330,334,337,340,343,345,348,351,354,357,359,361,364,366],{"class":269,"line":303},2,[267,305,306],{"class":281},"const",[267,308,309],{"class":273}," {",[267,311,312],{"class":277}," data",[267,314,315],{"class":273},":",[267,317,319],{"class":318},"sndM8"," navigation ",[267,321,322],{"class":273},"}",[267,324,325],{"class":273}," =",[267,327,329],{"class":328},"s8pZq"," await",[267,331,333],{"class":332},"swgpB"," useAsyncData",[267,335,336],{"class":318},"(",[267,338,339],{"class":273},"'",[267,341,342],{"class":294},"navigation",[267,344,339],{"class":273},[267,346,347],{"class":273},",",[267,349,350],{"class":273}," ()",[267,352,353],{"class":281}," =>",[267,355,356],{"class":332}," queryCollectionNavigation",[267,358,336],{"class":318},[267,360,339],{"class":273},[267,362,363],{"class":294},"docs",[267,365,339],{"class":273},[267,367,368],{"class":318},"))\n",[267,370,372,374,376,378,380,383,385,387,389,391,393,395,398,400,402,404,406,409,411,413,415,417],{"class":269,"line":371},3,[267,373,306],{"class":281},[267,375,309],{"class":273},[267,377,312],{"class":277},[267,379,315],{"class":273},[267,381,382],{"class":318}," files ",[267,384,322],{"class":273},[267,386,325],{"class":273},[267,388,329],{"class":328},[267,390,333],{"class":332},[267,392,336],{"class":318},[267,394,339],{"class":273},[267,396,397],{"class":294},"search",[267,399,339],{"class":273},[267,401,347],{"class":273},[267,403,350],{"class":273},[267,405,353],{"class":281},[267,407,408],{"class":332}," queryCollectionSearchSections",[267,410,336],{"class":318},[267,412,339],{"class":273},[267,414,363],{"class":294},[267,416,339],{"class":273},[267,418,368],{"class":318},[267,420,422],{"class":269,"line":421},4,[267,423,425],{"emptyLinePlaceholder":424},true,"\n",[267,427,429,431,434,436,439,441,444],{"class":269,"line":428},5,[267,430,306],{"class":281},[267,432,433],{"class":318}," searchTerm ",[267,435,288],{"class":273},[267,437,438],{"class":332}," ref",[267,440,336],{"class":318},[267,442,443],{"class":273},"''",[267,445,446],{"class":318},")\n",[267,448,450,453,455],{"class":269,"line":449},6,[267,451,452],{"class":273},"\u003C/",[267,454,278],{"class":277},[267,456,300],{"class":273},[267,458,460],{"class":269,"line":459},7,[267,461,425],{"emptyLinePlaceholder":424},[267,463,465,467,470],{"class":269,"line":464},8,[267,466,274],{"class":273},[267,468,469],{"class":277},"template",[267,471,300],{"class":273},[267,473,475,478],{"class":269,"line":474},9,[267,476,477],{"class":273},"  \u003C",[267,479,480],{"class":277},"UContentSearch\n",[267,482,484,487,489,491,494],{"class":269,"line":483},10,[267,485,486],{"class":281},"    v-model:search-term",[267,488,288],{"class":273},[267,490,291],{"class":273},[267,492,493],{"class":294},"searchTerm",[267,495,496],{"class":273},"\"\n",[267,498,500,503,505,507,509],{"class":269,"line":499},11,[267,501,502],{"class":281},"    :files",[267,504,288],{"class":273},[267,506,291],{"class":273},[267,508,244],{"class":294},[267,510,496],{"class":273},[267,512,514,517,519,521,523],{"class":269,"line":513},12,[267,515,516],{"class":281},"    :navigation",[267,518,288],{"class":273},[267,520,291],{"class":273},[267,522,342],{"class":294},[267,524,496],{"class":273},[267,526,528,531,533,535,538],{"class":269,"line":527},13,[267,529,530],{"class":281},"    :fuse",[267,532,288],{"class":273},[267,534,291],{"class":273},[267,536,537],{"class":294},"{ resultLimit: 42 }",[267,539,496],{"class":273},[267,541,543],{"class":269,"line":542},14,[267,544,545],{"class":273},"  />\n",[267,547,549,551,553],{"class":269,"line":548},15,[267,550,452],{"class":273},[267,552,469],{"class":277},[267,554,300],{"class":273},[556,557,559],"preview-card",{"label":558},"Live Preview",[560,561],"example-fulltext-content-search",{},[232,563,565],{"id":564},"minisearch-example","MiniSearch example",[202,567,248,568,252],{},[206,569,229],{"href":227,"rel":570},[216],[254,572,573,1139],{},[257,574,577],{"className":259,"code":575,"filename":576,"language":262,"meta":263,"style":263},"\u003Cscript setup lang=\"ts\">\nimport MiniSearch from 'minisearch'\n\nconst query = ref('')\nconst { data } = await useAsyncData('search', () => queryCollectionSearchSections('docs'))\n\nconst miniSearch = new MiniSearch({\n  fields: ['title', 'content'],\n  storeFields: ['title', 'content'],\n  searchOptions: {\n    prefix: true,\n    fuzzy: 0.2,\n  },\n})\n\n// Add data to the MiniSearch instance\nminiSearch.addAll(toValue(data.value))\nconst result = computed(() => miniSearch.search(toValue(query)))\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CUContainer class=\"p-4\">\n    \u003CUCard>\n      \u003CUInput v-model=\"query\" placeholder=\"Search...\" />\n      \u003Cul>\n        \u003Cli v-for=\"link of result\" :key=\"link.id\" class=\"mt-2\">\n          \u003CNuxtLink :to=\"link.id\">{{ link.title }}\u003C/NuxtLink>\n          \u003Cp class=\"text-gray-500 text-xs\">{{ link.content }}\u003C/p>\n        \u003C/li>\n      \u003C/ul>\n    \u003C/UCard>\n  \u003C/UContainer>\n\u003C/template>\n","MiniSearchExample.vue",[209,578,579,599,618,622,639,682,686,706,738,765,775,788,801,806,812,816,823,847,881,890,895,904,926,937,973,983,1029,1061,1090,1100,1110,1120,1130],{"__ignoreMap":263},[267,580,581,583,585,587,589,591,593,595,597],{"class":269,"line":270},[267,582,274],{"class":273},[267,584,278],{"class":277},[267,586,282],{"class":281},[267,588,285],{"class":281},[267,590,288],{"class":273},[267,592,291],{"class":273},[267,594,295],{"class":294},[267,596,291],{"class":273},[267,598,300],{"class":273},[267,600,601,604,607,610,613,615],{"class":269,"line":303},[267,602,603],{"class":328},"import",[267,605,606],{"class":318}," MiniSearch ",[267,608,609],{"class":328},"from",[267,611,612],{"class":273}," '",[267,614,229],{"class":294},[267,616,617],{"class":273},"'\n",[267,619,620],{"class":269,"line":371},[267,621,425],{"emptyLinePlaceholder":424},[267,623,624,626,629,631,633,635,637],{"class":269,"line":421},[267,625,306],{"class":281},[267,627,628],{"class":318}," query ",[267,630,288],{"class":273},[267,632,438],{"class":332},[267,634,336],{"class":318},[267,636,443],{"class":273},[267,638,446],{"class":318},[267,640,641,643,645,648,650,652,654,656,658,660,662,664,666,668,670,672,674,676,678,680],{"class":269,"line":428},[267,642,306],{"class":281},[267,644,309],{"class":273},[267,646,647],{"class":318}," data ",[267,649,322],{"class":273},[267,651,325],{"class":273},[267,653,329],{"class":328},[267,655,333],{"class":332},[267,657,336],{"class":318},[267,659,339],{"class":273},[267,661,397],{"class":294},[267,663,339],{"class":273},[267,665,347],{"class":273},[267,667,350],{"class":273},[267,669,353],{"class":281},[267,671,408],{"class":332},[267,673,336],{"class":318},[267,675,339],{"class":273},[267,677,363],{"class":294},[267,679,339],{"class":273},[267,681,368],{"class":318},[267,683,684],{"class":269,"line":449},[267,685,425],{"emptyLinePlaceholder":424},[267,687,688,690,693,695,698,701,703],{"class":269,"line":459},[267,689,306],{"class":281},[267,691,692],{"class":318}," miniSearch ",[267,694,288],{"class":273},[267,696,697],{"class":273}," new",[267,699,700],{"class":332}," MiniSearch",[267,702,336],{"class":318},[267,704,705],{"class":273},"{\n",[267,707,708,711,713,716,718,721,723,725,727,730,732,735],{"class":269,"line":464},[267,709,710],{"class":277},"  fields",[267,712,315],{"class":273},[267,714,715],{"class":318}," [",[267,717,339],{"class":273},[267,719,720],{"class":294},"title",[267,722,339],{"class":273},[267,724,347],{"class":273},[267,726,612],{"class":273},[267,728,729],{"class":294},"content",[267,731,339],{"class":273},[267,733,734],{"class":318},"]",[267,736,737],{"class":273},",\n",[267,739,740,743,745,747,749,751,753,755,757,759,761,763],{"class":269,"line":474},[267,741,742],{"class":277},"  storeFields",[267,744,315],{"class":273},[267,746,715],{"class":318},[267,748,339],{"class":273},[267,750,720],{"class":294},[267,752,339],{"class":273},[267,754,347],{"class":273},[267,756,612],{"class":273},[267,758,729],{"class":294},[267,760,339],{"class":273},[267,762,734],{"class":318},[267,764,737],{"class":273},[267,766,767,770,772],{"class":269,"line":483},[267,768,769],{"class":277},"  searchOptions",[267,771,315],{"class":273},[267,773,774],{"class":273}," {\n",[267,776,777,780,782,786],{"class":269,"line":499},[267,778,779],{"class":277},"    prefix",[267,781,315],{"class":273},[267,783,785],{"class":784},"sPKOg"," true",[267,787,737],{"class":273},[267,789,790,793,795,799],{"class":269,"line":513},[267,791,792],{"class":277},"    fuzzy",[267,794,315],{"class":273},[267,796,798],{"class":797},"smPcV"," 0.2",[267,800,737],{"class":273},[267,802,803],{"class":269,"line":527},[267,804,805],{"class":273},"  },\n",[267,807,808,810],{"class":269,"line":542},[267,809,322],{"class":273},[267,811,446],{"class":318},[267,813,814],{"class":269,"line":548},[267,815,425],{"emptyLinePlaceholder":424},[267,817,819],{"class":269,"line":818},16,[267,820,822],{"class":821},"syuKq","// Add data to the MiniSearch instance\n",[267,824,826,829,831,834,836,839,842,844],{"class":269,"line":825},17,[267,827,828],{"class":318},"miniSearch",[267,830,252],{"class":273},[267,832,833],{"class":332},"addAll",[267,835,336],{"class":318},[267,837,838],{"class":332},"toValue",[267,840,841],{"class":318},"(data",[267,843,252],{"class":273},[267,845,846],{"class":318},"value))\n",[267,848,850,852,855,857,860,862,865,867,870,872,874,876,878],{"class":269,"line":849},18,[267,851,306],{"class":281},[267,853,854],{"class":318}," result ",[267,856,288],{"class":273},[267,858,859],{"class":332}," computed",[267,861,336],{"class":318},[267,863,864],{"class":273},"()",[267,866,353],{"class":281},[267,868,869],{"class":318}," miniSearch",[267,871,252],{"class":273},[267,873,397],{"class":332},[267,875,336],{"class":318},[267,877,838],{"class":332},[267,879,880],{"class":318},"(query)))\n",[267,882,884,886,888],{"class":269,"line":883},19,[267,885,452],{"class":273},[267,887,278],{"class":277},[267,889,300],{"class":273},[267,891,893],{"class":269,"line":892},20,[267,894,425],{"emptyLinePlaceholder":424},[267,896,898,900,902],{"class":269,"line":897},21,[267,899,274],{"class":273},[267,901,469],{"class":277},[267,903,300],{"class":273},[267,905,907,909,912,915,917,919,922,924],{"class":269,"line":906},22,[267,908,477],{"class":273},[267,910,911],{"class":277},"UContainer",[267,913,914],{"class":281}," class",[267,916,288],{"class":273},[267,918,291],{"class":273},[267,920,921],{"class":294},"p-4",[267,923,291],{"class":273},[267,925,300],{"class":273},[267,927,929,932,935],{"class":269,"line":928},23,[267,930,931],{"class":273},"    \u003C",[267,933,934],{"class":277},"UCard",[267,936,300],{"class":273},[267,938,940,943,946,949,951,953,956,958,961,963,965,968,970],{"class":269,"line":939},24,[267,941,942],{"class":273},"      \u003C",[267,944,945],{"class":277},"UInput",[267,947,948],{"class":281}," v-model",[267,950,288],{"class":273},[267,952,291],{"class":273},[267,954,955],{"class":294},"query",[267,957,291],{"class":273},[267,959,960],{"class":281}," placeholder",[267,962,288],{"class":273},[267,964,291],{"class":273},[267,966,967],{"class":294},"Search...",[267,969,291],{"class":273},[267,971,972],{"class":273}," />\n",[267,974,976,978,981],{"class":269,"line":975},25,[267,977,942],{"class":273},[267,979,980],{"class":277},"ul",[267,982,300],{"class":273},[267,984,986,989,992,995,997,999,1002,1004,1007,1009,1011,1014,1016,1018,1020,1022,1025,1027],{"class":269,"line":985},26,[267,987,988],{"class":273},"        \u003C",[267,990,991],{"class":277},"li",[267,993,994],{"class":281}," v-for",[267,996,288],{"class":273},[267,998,291],{"class":273},[267,1000,1001],{"class":294},"link of result",[267,1003,291],{"class":273},[267,1005,1006],{"class":281}," :key",[267,1008,288],{"class":273},[267,1010,291],{"class":273},[267,1012,1013],{"class":294},"link.id",[267,1015,291],{"class":273},[267,1017,914],{"class":281},[267,1019,288],{"class":273},[267,1021,291],{"class":273},[267,1023,1024],{"class":294},"mt-2",[267,1026,291],{"class":273},[267,1028,300],{"class":273},[267,1030,1032,1035,1038,1041,1043,1045,1047,1049,1052,1055,1057,1059],{"class":269,"line":1031},27,[267,1033,1034],{"class":273},"          \u003C",[267,1036,1037],{"class":277},"NuxtLink",[267,1039,1040],{"class":281}," :to",[267,1042,288],{"class":273},[267,1044,291],{"class":273},[267,1046,1013],{"class":294},[267,1048,291],{"class":273},[267,1050,1051],{"class":273},">",[267,1053,1054],{"class":318},"{{ link.title }}",[267,1056,452],{"class":273},[267,1058,1037],{"class":277},[267,1060,300],{"class":273},[267,1062,1064,1066,1068,1070,1072,1074,1077,1079,1081,1084,1086,1088],{"class":269,"line":1063},28,[267,1065,1034],{"class":273},[267,1067,202],{"class":277},[267,1069,914],{"class":281},[267,1071,288],{"class":273},[267,1073,291],{"class":273},[267,1075,1076],{"class":294},"text-gray-500 text-xs",[267,1078,291],{"class":273},[267,1080,1051],{"class":273},[267,1082,1083],{"class":318},"{{ link.content }}",[267,1085,452],{"class":273},[267,1087,202],{"class":277},[267,1089,300],{"class":273},[267,1091,1093,1096,1098],{"class":269,"line":1092},29,[267,1094,1095],{"class":273},"        \u003C/",[267,1097,991],{"class":277},[267,1099,300],{"class":273},[267,1101,1103,1106,1108],{"class":269,"line":1102},30,[267,1104,1105],{"class":273},"      \u003C/",[267,1107,980],{"class":277},[267,1109,300],{"class":273},[267,1111,1113,1116,1118],{"class":269,"line":1112},31,[267,1114,1115],{"class":273},"    \u003C/",[267,1117,934],{"class":277},[267,1119,300],{"class":273},[267,1121,1123,1126,1128],{"class":269,"line":1122},32,[267,1124,1125],{"class":273},"  \u003C/",[267,1127,911],{"class":277},[267,1129,300],{"class":273},[267,1131,1133,1135,1137],{"class":269,"line":1132},33,[267,1134,452],{"class":273},[267,1136,469],{"class":277},[267,1138,300],{"class":273},[556,1140,1141],{"label":558},[1142,1143],"example-fulltext-mini-search",{},[232,1145,1147],{"id":1146},"fusejs-example","Fuse.js example",[202,1149,248,1150,252],{},[206,1151,223],{"href":1152,"rel":1153},"https://fusejs.io",[216],[254,1155,1156,1634],{},[257,1157,1160],{"className":259,"code":1158,"filename":1159,"language":262,"meta":263,"style":263},"\u003Cscript setup lang=\"ts\">\nimport Fuse from 'fuse.js'\n\nconst query = ref('')\nconst { data } = await useAsyncData('search-data', () => queryCollectionSearchSections('docs'))\n\nconst fuse = new Fuse(data.value, {\n  keys: ['title', 'description']\n})\n\nconst result = computed(() => fuse.search(toValue(query)).slice(0, 10))\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CUContainer class=\"p-4\">\n    \u003CUCard>\n      \u003CUInput v-model=\"query\" placeholder=\"Search...\" class=\"w-full\" />\n      \u003Cul>\n        \u003Cli v-for=\"link of result\" :key=\"link.item.id\" class=\"mt-2\">\n          \u003CUButton variant=\"ghost\" class=\"w-full\" :to=\"link.item.id\">\n            {{ link.item.title }}\n            \u003Cspan class=\"text-gray-500 text-xs\">\n              {{ link.item.content?.slice(0, 100) }}...\n            \u003C/span>\n          \u003C/UButton>\n        \u003C/li>\n      \u003C/ul>\n    \u003C/UCard>\n  \u003C/UContainer>\n\u003C/template>\n","FusejsExample.vue",[209,1161,1162,1182,1198,1202,1218,1261,1265,1290,1317,1323,1327,1374,1382,1386,1394,1412,1420,1459,1467,1506,1547,1552,1571,1576,1585,1594,1602,1610,1618,1626],{"__ignoreMap":263},[267,1163,1164,1166,1168,1170,1172,1174,1176,1178,1180],{"class":269,"line":270},[267,1165,274],{"class":273},[267,1167,278],{"class":277},[267,1169,282],{"class":281},[267,1171,285],{"class":281},[267,1173,288],{"class":273},[267,1175,291],{"class":273},[267,1177,295],{"class":294},[267,1179,291],{"class":273},[267,1181,300],{"class":273},[267,1183,1184,1186,1189,1191,1193,1196],{"class":269,"line":303},[267,1185,603],{"class":328},[267,1187,1188],{"class":318}," Fuse ",[267,1190,609],{"class":328},[267,1192,612],{"class":273},[267,1194,1195],{"class":294},"fuse.js",[267,1197,617],{"class":273},[267,1199,1200],{"class":269,"line":371},[267,1201,425],{"emptyLinePlaceholder":424},[267,1203,1204,1206,1208,1210,1212,1214,1216],{"class":269,"line":421},[267,1205,306],{"class":281},[267,1207,628],{"class":318},[267,1209,288],{"class":273},[267,1211,438],{"class":332},[267,1213,336],{"class":318},[267,1215,443],{"class":273},[267,1217,446],{"class":318},[267,1219,1220,1222,1224,1226,1228,1230,1232,1234,1236,1238,1241,1243,1245,1247,1249,1251,1253,1255,1257,1259],{"class":269,"line":428},[267,1221,306],{"class":281},[267,1223,309],{"class":273},[267,1225,647],{"class":318},[267,1227,322],{"class":273},[267,1229,325],{"class":273},[267,1231,329],{"class":328},[267,1233,333],{"class":332},[267,1235,336],{"class":318},[267,1237,339],{"class":273},[267,1239,1240],{"class":294},"search-data",[267,1242,339],{"class":273},[267,1244,347],{"class":273},[267,1246,350],{"class":273},[267,1248,353],{"class":281},[267,1250,408],{"class":332},[267,1252,336],{"class":318},[267,1254,339],{"class":273},[267,1256,363],{"class":294},[267,1258,339],{"class":273},[267,1260,368],{"class":318},[267,1262,1263],{"class":269,"line":449},[267,1264,425],{"emptyLinePlaceholder":424},[267,1266,1267,1269,1272,1274,1276,1279,1281,1283,1286,1288],{"class":269,"line":459},[267,1268,306],{"class":281},[267,1270,1271],{"class":318}," fuse ",[267,1273,288],{"class":273},[267,1275,697],{"class":273},[267,1277,1278],{"class":332}," Fuse",[267,1280,841],{"class":318},[267,1282,252],{"class":273},[267,1284,1285],{"class":318},"value",[267,1287,347],{"class":273},[267,1289,774],{"class":273},[267,1291,1292,1295,1297,1299,1301,1303,1305,1307,1309,1312,1314],{"class":269,"line":464},[267,1293,1294],{"class":277},"  keys",[267,1296,315],{"class":273},[267,1298,715],{"class":318},[267,1300,339],{"class":273},[267,1302,720],{"class":294},[267,1304,339],{"class":273},[267,1306,347],{"class":273},[267,1308,612],{"class":273},[267,1310,1311],{"class":294},"description",[267,1313,339],{"class":273},[267,1315,1316],{"class":318},"]\n",[267,1318,1319,1321],{"class":269,"line":474},[267,1320,322],{"class":273},[267,1322,446],{"class":318},[267,1324,1325],{"class":269,"line":483},[267,1326,425],{"emptyLinePlaceholder":424},[267,1328,1329,1331,1333,1335,1337,1339,1341,1343,1346,1348,1350,1352,1354,1357,1359,1362,1364,1367,1369,1372],{"class":269,"line":499},[267,1330,306],{"class":281},[267,1332,854],{"class":318},[267,1334,288],{"class":273},[267,1336,859],{"class":332},[267,1338,336],{"class":318},[267,1340,864],{"class":273},[267,1342,353],{"class":281},[267,1344,1345],{"class":318}," fuse",[267,1347,252],{"class":273},[267,1349,397],{"class":332},[267,1351,336],{"class":318},[267,1353,838],{"class":332},[267,1355,1356],{"class":318},"(query))",[267,1358,252],{"class":273},[267,1360,1361],{"class":332},"slice",[267,1363,336],{"class":318},[267,1365,1366],{"class":797},"0",[267,1368,347],{"class":273},[267,1370,1371],{"class":797}," 10",[267,1373,368],{"class":318},[267,1375,1376,1378,1380],{"class":269,"line":513},[267,1377,452],{"class":273},[267,1379,278],{"class":277},[267,1381,300],{"class":273},[267,1383,1384],{"class":269,"line":527},[267,1385,425],{"emptyLinePlaceholder":424},[267,1387,1388,1390,1392],{"class":269,"line":542},[267,1389,274],{"class":273},[267,1391,469],{"class":277},[267,1393,300],{"class":273},[267,1395,1396,1398,1400,1402,1404,1406,1408,1410],{"class":269,"line":548},[267,1397,477],{"class":273},[267,1399,911],{"class":277},[267,1401,914],{"class":281},[267,1403,288],{"class":273},[267,1405,291],{"class":273},[267,1407,921],{"class":294},[267,1409,291],{"class":273},[267,1411,300],{"class":273},[267,1413,1414,1416,1418],{"class":269,"line":818},[267,1415,931],{"class":273},[267,1417,934],{"class":277},[267,1419,300],{"class":273},[267,1421,1422,1424,1426,1428,1430,1432,1434,1436,1438,1440,1442,1444,1446,1448,1450,1452,1455,1457],{"class":269,"line":825},[267,1423,942],{"class":273},[267,1425,945],{"class":277},[267,1427,948],{"class":281},[267,1429,288],{"class":273},[267,1431,291],{"class":273},[267,1433,955],{"class":294},[267,1435,291],{"class":273},[267,1437,960],{"class":281},[267,1439,288],{"class":273},[267,1441,291],{"class":273},[267,1443,967],{"class":294},[267,1445,291],{"class":273},[267,1447,914],{"class":281},[267,1449,288],{"class":273},[267,1451,291],{"class":273},[267,1453,1454],{"class":294},"w-full",[267,1456,291],{"class":273},[267,1458,972],{"class":273},[267,1460,1461,1463,1465],{"class":269,"line":849},[267,1462,942],{"class":273},[267,1464,980],{"class":277},[267,1466,300],{"class":273},[267,1468,1469,1471,1473,1475,1477,1479,1481,1483,1485,1487,1489,1492,1494,1496,1498,1500,1502,1504],{"class":269,"line":883},[267,1470,988],{"class":273},[267,1472,991],{"class":277},[267,1474,994],{"class":281},[267,1476,288],{"class":273},[267,1478,291],{"class":273},[267,1480,1001],{"class":294},[267,1482,291],{"class":273},[267,1484,1006],{"class":281},[267,1486,288],{"class":273},[267,1488,291],{"class":273},[267,1490,1491],{"class":294},"link.item.id",[267,1493,291],{"class":273},[267,1495,914],{"class":281},[267,1497,288],{"class":273},[267,1499,291],{"class":273},[267,1501,1024],{"class":294},[267,1503,291],{"class":273},[267,1505,300],{"class":273},[267,1507,1508,1510,1513,1516,1518,1520,1523,1525,1527,1529,1531,1533,1535,1537,1539,1541,1543,1545],{"class":269,"line":892},[267,1509,1034],{"class":273},[267,1511,1512],{"class":277},"UButton",[267,1514,1515],{"class":281}," variant",[267,1517,288],{"class":273},[267,1519,291],{"class":273},[267,1521,1522],{"class":294},"ghost",[267,1524,291],{"class":273},[267,1526,914],{"class":281},[267,1528,288],{"class":273},[267,1530,291],{"class":273},[267,1532,1454],{"class":294},[267,1534,291],{"class":273},[267,1536,1040],{"class":281},[267,1538,288],{"class":273},[267,1540,291],{"class":273},[267,1542,1491],{"class":294},[267,1544,291],{"class":273},[267,1546,300],{"class":273},[267,1548,1549],{"class":269,"line":897},[267,1550,1551],{"class":318},"            {{ link.item.title }}\n",[267,1553,1554,1557,1559,1561,1563,1565,1567,1569],{"class":269,"line":906},[267,1555,1556],{"class":273},"            \u003C",[267,1558,267],{"class":277},[267,1560,914],{"class":281},[267,1562,288],{"class":273},[267,1564,291],{"class":273},[267,1566,1076],{"class":294},[267,1568,291],{"class":273},[267,1570,300],{"class":273},[267,1572,1573],{"class":269,"line":928},[267,1574,1575],{"class":318},"              {{ link.item.content?.slice(0, 100) }}...\n",[267,1577,1578,1581,1583],{"class":269,"line":939},[267,1579,1580],{"class":273},"            \u003C/",[267,1582,267],{"class":277},[267,1584,300],{"class":273},[267,1586,1587,1590,1592],{"class":269,"line":975},[267,1588,1589],{"class":273},"          \u003C/",[267,1591,1512],{"class":277},[267,1593,300],{"class":273},[267,1595,1596,1598,1600],{"class":269,"line":985},[267,1597,1095],{"class":273},[267,1599,991],{"class":277},[267,1601,300],{"class":273},[267,1603,1604,1606,1608],{"class":269,"line":1031},[267,1605,1105],{"class":273},[267,1607,980],{"class":277},[267,1609,300],{"class":273},[267,1611,1612,1614,1616],{"class":269,"line":1063},[267,1613,1115],{"class":273},[267,1615,934],{"class":277},[267,1617,300],{"class":273},[267,1619,1620,1622,1624],{"class":269,"line":1092},[267,1621,1125],{"class":273},[267,1623,911],{"class":277},[267,1625,300],{"class":273},[267,1627,1628,1630,1632],{"class":269,"line":1102},[267,1629,452],{"class":273},[267,1631,469],{"class":277},[267,1633,300],{"class":273},[556,1635,1636],{"label":558},[1637,1638],"example-fulltext-fusejs",{},[1640,1641,1642],"style",{},"html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sPKOg, html code.shiki .sPKOg{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .smPcV, html code.shiki .smPcV{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .syuKq, html code.shiki .syuKq{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":263,"searchDepth":421,"depth":421,"links":1644},[1645,1646,1647],{"id":234,"depth":303,"text":235},{"id":564,"depth":303,"text":565},{"id":1146,"depth":303,"text":1147},"Implement full-text search in your website using Nuxt Content","md",null,{},{"title":142,"description":1648},[1654,1656],{"title":132,"path":133,"stem":134,"description":1655,"children":-1},"How to deploy Nuxt Content to static hosting with static site generation.",{"title":146,"path":147,"stem":148,"description":1657,"children":-1},"Access to contents raw data in appliction",{"data":1659,"body":1660,"excerpt":-1,"toc":1669},{"title":263,"description":1648},{"type":1661,"children":1662},"root",[1663],{"type":1664,"tag":202,"props":1665,"children":1666},"element",{},[1667],{"type":1668,"value":1648},"text",{"title":263,"searchDepth":303,"depth":303,"links":1670},[],[1672,1676,1680,1685,1690,1695,1700,1705,1708,1713,1718,1723,1728,1733,1736,1741,1746,1751,1756,1761,1766,1771,1776,1781,1786,1791,1796,1801,1806,1811,1816,1821,1826,1831,1836,1839,1843,1848,1852,1856,1861,1866,1871,1876,1881,1886,1891,1896,1900,1905,1910,1915,1920,1925,1929,1934,1939,1944,1949,1954,1958,1963,1968,1973,1978,1983,1988,1993,1996,2000,2005,2010,2015,2020,2025,2030,2035,2040,2045,2050,2055,2060,2065,2070,2075,2080,2085,2090,2094,2099,2104,2109,2112,2117,2122,2127,2130,2134,2139,2142,2145,2149,2153,2158,2163,2168,2173,2178,2183,2188,2193,2198,2203,2208,2213,2218,2223,2226,2230,2234,2239,2242,2247,2251,2255,2258,2262,2266,2269,2274,2278,2282,2285,2289,2293,2296,2301,2306,2310,2313,2317,2322,2327,2332,2335,2339,2344,2349,2353,2356,2361,2366,2371,2376,2381,2386,2391,2396,2401,2406,2411,2416,2421,2426,2431,2436,2441,2446,2451,2456,2460,2464,2468,2473,2477,2482,2487,2491,2496,2501,2506,2511,2516,2519,2522,2525,2528,2533,2538,2541,2546,2551,2556,2559,2563,2567,2571,2574,2578,2583,2588,2593,2597,2602,2607,2612,2616,2621,2626,2631,2634,2639,2644,2647,2651,2656,2661,2666,2671,2675,2680,2684,2689,2694,2699,2703,2708,2712,2717,2721,2725,2730,2735,2740,2745,2749,2754,2759,2763,2768,2773,2778,2783,2788,2791,2796],{"id":6,"title":1673,"titles":1674,"content":1675,"level":270},"Nuxt Content v3",[],"The powerful Git-based CMS designed specifically for Nuxt developers. Welcome to Nuxt Content v3, a major upgrade that brings enhanced performance and innovative features to your Nuxt projects. This latest iteration of our Git-based CMS is optimized for modern application development.",{"id":1677,"title":1678,"titles":1679,"content":263,"level":303},"/docs/getting-started#whats-new","What's New?",[1673],{"id":1681,"title":1682,"titles":1683,"content":1684,"level":371},"/docs/getting-started#content-collections","Content Collections",[1673,1678],"Collections organize related items within your project, helping you manage large datasets more efficiently. Key benefits include: Structured Data: Configure database architecture and define collections in content.config.tsType-safe Queries: Direct TypeScript integration across all utilitiesAutomatic Validation: Ensure data consistency across frontmatter fields and data files (json, yml...)Advanced Query Builder: Filter, sort, and paginate your collections with easeStudio Integration: Enhanced form generation and optimal editing experience through Studio Learn more about Content Collections.",{"id":1686,"title":1687,"titles":1688,"content":1689,"level":371},"/docs/getting-started#improved-performance","Improved Performance",[1673,1678],"A significant challenge in v2 was the large bundle size needed for storing files, particularly affecting serverless deployments. V3 addresses this by transitioning to SQL-based storage in production. This switch requires zero configuration, supporting development mode, static generation, server hosting, serverless and edge deployments. The new database system enhances the way your data files are stored and structured, ensuring better performance and scalability. This update is entirely behind the scenes and does not affect the file types you can use in Content (yml, json, and markdown ). Benefits include: Optimized Queries: SQL storage enables ultra-fast data retrievalUniversal Compatibility: Our adapter-based system integrates SQL databases across all deployment modes (server, serverless and static). We welcome community contributions for additional adapters.",{"id":1691,"title":1692,"titles":1693,"content":1694,"level":371},"/docs/getting-started#typescript-integration","TypeScript Integration",[1673,1678],"The new collections system provides automatic TypeScript types for all your data. Every utility and API is strongly typed based on your collection definitions, ensuring robust type safety throughout development.",{"id":1696,"title":1697,"titles":1698,"content":1699,"level":371},"/docs/getting-started#nuxt-studio-integration-soon","Nuxt Studio Integration Soon",[1673,1678],"Nuxt Studio and v3 are designed to complement each other perfectly.. The studio module is now integrated directly into Nuxt Content, creating an ideal environment where developers can focus on code while team members manage content through an intuitive interface. We're excited for you to explore these new capabilities. Dive into our documentation to learn more about integrating the module and implementing best practices in your next project.",{"id":1701,"title":1702,"titles":1703,"content":1704,"level":303},"/docs/getting-started#content-v2-migration","Content V2 Migration",[1673],"Learn how to migrate from Content v2 to v3 in the migration guide.",{"id":13,"title":12,"titles":1706,"content":1707,"level":270},[],"Get started with Nuxt Content v3 in your Nuxt application.",{"id":1709,"title":1710,"titles":1711,"content":1712,"level":371},"/docs/getting-started/installation#install-the-package","Install the Package",[12],"Choose your preferred package manager to install Nuxt Content v3: pnpm add @nuxt/content\nyarn add @nuxt/content\nnpm install @nuxt/content\nbun add @nuxt/content",{"id":1714,"title":1715,"titles":1716,"content":1717,"level":371},"/docs/getting-started/installation#register-the-module","Register the Module",[12],"Add the Nuxt Content module to your nuxt.config.ts: export default defineNuxtConfig({\n  modules: ['@nuxt/content']\n})",{"id":1719,"title":1720,"titles":1721,"content":1722,"level":371},"/docs/getting-started/installation#create-your-first-collection","Create your First Collection",[12],"Create a content.config.ts file in your project root directory: import { defineContentConfig, defineCollection } from '@nuxt/content'\n\nexport default defineContentConfig({\n  collections: {\n    content: defineCollection({\n      type: 'page',\n      source: '**/*.md'\n    })\n  }\n}) This configuration creates a default content collection that processes all Markdown files located in the content folder of your project. You can customize the collection settings based on your needs. The type: page means there is a 1-to-1 relationship between content files and pages on your site. Learn more in our Collections guide.",{"id":1724,"title":1725,"titles":1726,"content":1727,"level":371},"/docs/getting-started/installation#create-your-first-markdown-page","Create your First Markdown Page",[12],"Create a content/index.md file in your project root directory: # My First Page\n\nHere is some content. Read more about writing Markdown pages.",{"id":1729,"title":1730,"titles":1731,"content":1732,"level":371},"/docs/getting-started/installation#display-your-page","Display your Page",[12],"Create a pages/index.vue file and display the page content: \u003Cscript setup lang=\"ts\">\nconst { data: home } = await useAsyncData(() => queryCollection('content').path('/').first())\n\nuseSeoMeta({\n  title: home.value?.title,\n  description: home.value?.description\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CContentRenderer v-if=\"home\" :value=\"home\" />\n  \u003Cdiv v-else>Home not found\u003C/div>\n\u003C/template> That's it! You've now created your first Nuxt Content page. html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}",{"id":17,"title":16,"titles":1734,"content":1735,"level":270},[],"Nuxt Content is configured with sensible defaults. To configure the content module and customize its behavior, you can use the content property in your nuxt.config: export default defineNuxtConfig({\n  content: {\n    // Options\n  }\n}) In addition to configuring via content.markdown, you can use Markdown Components (MDC) to customize the rendering of Markdown elements with mdc property.",{"id":1737,"title":1738,"titles":1739,"content":1740,"level":303},"/docs/getting-started/configuration#build","build",[16],"Nuxt Content read and parse all the available contents at build time. This option gives you control over parsing contents.",{"id":1742,"title":1743,"titles":1744,"content":1745,"level":371},"/docs/getting-started/configuration#markdown","markdown",[16,1738],"Configure markdown parser.",{"id":1747,"title":1748,"titles":1749,"content":1750,"level":421},"/docs/getting-started/configuration#toc","toc",[16,1738,1743],"toc: {\n  depth: 2,\n  searchDepth: 2\n}\ntype Toc = {\n  depth: number\n  searchDepth: number\n} Control behavior of Table of Contents generation. Value: depth: Maximum heading depth to include in the table of contents.searchDepth: Maximum depth of nested tags to search for heading. export default defineNuxtConfig({\n  content: {\n    build: {\n      markdown: {\n        toc: {\n          depth: 3, // include h3 headings\n        }\n      }\n    }\n  }\n})",{"id":1752,"title":1753,"titles":1754,"content":1755,"level":421},"/docs/getting-started/configuration#remarkplugins","remarkPlugins",[16,1738,1743],"remarkPlugins: {}\ntype RemarkPlugins = Record\u003Cstring, false | MarkdownPlugin> A list of remark plugins to use. export default defineNuxtConfig({\n  content: {\n    build: {\n      markdown: {\n        // Object syntax can be used to override default options\n        remarkPlugins: {\n          // Override remark-emoji options\n          'remark-emoji': {\n            options: {\n              emoticon: true\n            }\n          },\n          // Disable remark-gfm\n          'remark-gfm': false,\n          // Add remark-oembed\n          'remark-oembed': {\n            // Options\n          }\n        },\n      }\n    }\n  }\n})",{"id":1757,"title":1758,"titles":1759,"content":1760,"level":421},"/docs/getting-started/configuration#rehypeplugins","rehypePlugins",[16,1738,1743],"rehypePlugins: {}\ntype RehypePlugins = object A list of rehype plugins to use. export default defineNuxtConfig({\n  content: {\n    build: {\n      markdown: {\n        // Object syntax can be used to override default options\n        rehypePlugins: {\n          'rehype-figure': {\n\n          }\n        },\n      }\n    }\n  }\n})",{"id":1762,"title":1763,"titles":1764,"content":1765,"level":421},"/docs/getting-started/configuration#highlight","highlight",[16,1738,1743],"highlight: false\ntype Highlight = false | object Nuxt Content uses Shiki to provide syntax highlighting for ProsePre and ProseCode. OptionTypeDescriptionthemeShikiTheme or Record\u003Cstring, ShikiTheme>The color theme to use.langsShikiLang[]The loaded languages available for highlighting. highlight.theme Theme can be specified by a single string but also supports an object with multiple themes. This option is compatible with Color Mode module. If you are using multiple themes, it's recommended to always have a default theme specified. export default defineNuxtConfig({\n  content: {\n    build: {\n      markdown: {\n        highlight: {\n          // Theme used in all color schemes.\n          theme: 'github-light',\n          // OR\n          theme: {\n            // Default theme (same as single string)\n            default: 'github-light',\n            // Theme used if `html.dark`\n            dark: 'github-dark',\n            // Theme used if `html.sepia`\n            sepia: 'monokai'\n          }\n        }\n      }\n    }\n  }\n}) highlight.langs By default, the module loads a couple of languages for syntax highlighting: ['json', 'js', 'ts', 'html', 'css', 'vue', 'shell', 'mdc', 'md', 'yaml'] If you plan to use code samples of other languages, you need to define the language in these options. export default defineNuxtConfig({\n  content: {\n    build: {\n      markdown: {\n        highlight: {\n          langs: [\n            'c',\n            'cpp',\n            'java'\n          ]\n        }\n      }\n    }\n  }\n}) If you wish to add highlighting for an unsupported language, you can do so by loading the grammar file for the language. import { readFileSync } from 'node:fs'\n\nexport default defineNuxtConfig({\n  content: {\n    build: {\n      markdown: {\n        highlight: {\n          langs: [\n            // Read more about Shiki languages: https://shiki.style/guide/load-lang\n            JSON.parse(\n              readFileSync('./shiki/languages/gdscript.tmLanguage.json', 'utf-8'),\n            ),\n          ]\n        }\n      }\n    }\n  }\n}) Read more about adding languages in the Shiki documentation.",{"id":1767,"title":1768,"titles":1769,"content":1770,"level":371},"/docs/getting-started/configuration#pathmeta","pathMeta",[16,1738],"Content module uses files path to generate the slug, default title and content order, you can customize this behavior with pathMeta option.",{"id":1772,"title":1773,"titles":1774,"content":1775,"level":421},"/docs/getting-started/configuration#pathmetaforceleadingslash","pathMeta.forceLeadingSlash",[16,1738,1768],"If set to true, the path will be prefixed with a leading slash. Default value is true.",{"id":1777,"title":1778,"titles":1779,"content":1780,"level":421},"/docs/getting-started/configuration#pathmetaslugifyoptions","pathMeta.slugifyOptions",[16,1738,1768],"Content module uses slugify to generate the slug, you can customize the behavior of slugify with this option. Checkout slugify options for more information.",{"id":1782,"title":1783,"titles":1784,"content":1785,"level":371},"/docs/getting-started/configuration#transformers","transformers",[16,1738],"Nuxt Content has specific transformers for each content type to parse the raw content and prepare it for querying and rendering. Using this option you can define custom transformers to support new content types or improve functionalities of supported content types. export default defineNuxtConfig({\n  content: {\n    build: {\n      transformers: [\n        '~/transformers/title-suffix',\n      ],\n    },\n  },\n})\nimport { defineTransformer } from '@nuxt/content'\n\nexport default defineTransformer({\n  name: 'title-suffix',\n  extensions: ['.md'],\n  transform(file) {\n    return {\n      ...file,\n      title: file.title + ' (suffix)',\n    }\n  },\n})",{"id":1787,"title":1788,"titles":1789,"content":1790,"level":303},"/docs/getting-started/configuration#database","database",[16],"By default Nuxt Content uses a local SQLite database to store and query content. If you like to use another database or you plan to deploy on Cloudflare Workers, you can modify this option. Here is the list of supported database adapters:",{"id":1792,"title":1793,"titles":1794,"content":1795,"level":371},"/docs/getting-started/configuration#sqlite","SQLite",[16,1788],"If you want to change the default database location and move it to elsewhere you can use sqlite adapter to do so. This is the default value to the database option. Depending on your runtime-environment different sqlite adapters will be used (Node: better-sqlite-3, Bun: bun:sqlite). export default defineNuxtConfig({\n  content: {\n    database: {\n      type: 'sqlite',\n      filename: 'SQLITE_DB_LOCATION'\n    }\n  }\n})",{"id":1797,"title":1798,"titles":1799,"content":1800,"level":371},"/docs/getting-started/configuration#d1","D1",[16,1788],"If you plan to deploy your application to Cloudflare workers, you need to use the d1 database adapter. Create a d1 binding in the Cloudflare dashboard and fill in the bindingName field. export default defineNuxtConfig({\n  content: {\n    database: {\n      type: 'd1',\n      bindingName: 'CF_BINDING_NAME'\n    }\n  }\n})",{"id":1802,"title":1803,"titles":1804,"content":1805,"level":371},"/docs/getting-started/configuration#postgres","Postgres",[16,1788],"If you plan to deploy your application using PostgreSQL database you need to use the postgres database adapter. First, make sure to install the pg package: npx npm i pg Then, configure the postgres adapter in your nuxt.config.ts: export default defineNuxtConfig({\n  content: {\n    database: {\n      type: 'postgres',\n      url: process.env.POSTGRES_URL,\n      /* Other options for `pg` */\n    }\n  }\n})",{"id":1807,"title":1808,"titles":1809,"content":1810,"level":371},"/docs/getting-started/configuration#libsql","LibSQL",[16,1788],"If you plan to deploy your application using a LibSQL database you need to use the libsql database adapter. First, make sure to install the @libsql/client package: npx npm i @libsql/client Then, configure the libsql adapter in your nuxt.config.ts: export default defineNuxtConfig({\n  content: {\n    database: {\n      type: 'libsql',\n      url: process.env.TURSO_DATABASE_URL,\n      authToken: process.env.TURSO_AUTH_TOKEN,\n    }\n  }\n}) The most popular LibSQL hosting services is Turso.",{"id":1812,"title":1813,"titles":1814,"content":1815,"level":303},"/docs/getting-started/configuration#renderer","renderer",[16],"Configure content renderer.",{"id":1817,"title":1818,"titles":1819,"content":1820,"level":371},"/docs/getting-started/configuration#anchorlinks","anchorLinks",[16,1813],"{ h2: true, h3: true, h4: true }\ntype AnchorLinks = boolean | Record\u003C'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6', boolean> Control anchor link generation, by default it generates anchor links for h2, h3 and h4 heading Value: false: will disable link generation.true: will enable link generation for all headings.",{"id":1822,"title":1823,"titles":1824,"content":1825,"level":371},"/docs/getting-started/configuration#alias","alias",[16,1813],"alias: {}\ntype Alias = Record\u003Cstring, string> Aliases will be used to replace markdown components and render custom components instead of default ones. export default defineNuxtConfig({\n  content: {\n    renderer: {\n      alias: {\n        p: 'MyCustomParagraph'\n      }\n    }\n  }\n})",{"id":1827,"title":1828,"titles":1829,"content":1830,"level":303},"/docs/getting-started/configuration#watch","watch",[16],"watch: {\n  enabled: true,\n  ws: { port: 4000, showURL: false }\n} Configure content hot reload in development. Value: enabled: Enable/Disable hot reload.port: Select the port used for the WebSocket server.showURL: Toggle URL display in dev server boot message. The watcher is a development feature and will not be included in production. export default defineNuxtConfig({\n  content: {\n    watch: {\n      ws: {\n        port: 4000,\n        showURL: true\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  content: {\n    watch: {\n      enabled: false\n    }\n  }\n})",{"id":1832,"title":1833,"titles":1834,"content":1835,"level":303},"/docs/getting-started/configuration#preview","preview",[16],"Enable Preview API This is needed to enable live preview on Nuxt Studio. Value: dev: Enable in development modeapi: Activate the preview mode and set the API to be linked with. preview: {\n  api: 'https://api.nuxt.studio',\n} html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .syuKq, html code.shiki .syuKq{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .smPcV, html code.shiki .smPcV{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sPKOg, html code.shiki .sPKOg{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sK9QF, html code.shiki .sK9QF{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"id":21,"title":20,"titles":1837,"content":1838,"level":270},[],"How to migrate from v2 to v3 Nuxt Content v3 has been rebuilt from the ground up, resulting in a new library with enhanced capabilities. While we've redesigned concepts and components in a similar way as Content v2, breaking changes are inevitable. Don't worry, you don't need to modify your content files. We made sure that Content v3 handles content in the same way as Content v2.",{"id":1840,"title":1841,"titles":1842,"content":263,"level":303},"/docs/getting-started/migration#changes","Changes",[20],{"id":1844,"title":1845,"titles":1846,"content":1847,"level":371},"/docs/getting-started/migration#vue-utils","Vue utils",[20,1841],"queryContent() API is replaced with new queryCollection() The new API is backed by SQL and content queries happens within a specific collection. fetchContentNavigation() API is replaced with new queryCollectionNavigation()Surroundings now has its own separate API queryCollectionItemSurroundings()Document driven mode is dropped: Markdown files will not convert to Nuxt pages automatically, you need to create pages, check this section to see how.useContent() composable is removedsearchContent() is dropped in favor of the new queryCollectionSearchSections APIFull text search can easily be done using the queryCollectionSearchSections API, check this section to see how",{"id":1849,"title":84,"titles":1850,"content":1851,"level":371},"/docs/getting-started/migration#components",[20,1841],"All content should be rendered using \u003CContentRenderer> component. \u003CContentDoc>, \u003CContentList>, \u003CContentNavigation> and \u003CContentQuery> components are dropped in v3.\u003CContentSlot> and \u003CMDCSlot> components are not supported in v3. Instead components can simply use Vue's native \u003Cslot> component \u003CContentSlot> and \u003CMDCSlot> was initially pro to manipulate content before rendering and removing wrapping paragraphs from slot content. This unwrapping behavior is now supported via mdc-unwrap attribute in \u003Cslot> component. Example: \u003Cslot mdc-unwrap=\"p\" /> Components created under the components/content directory are no longer automatically registered as global components. If you use dynamic rendering to render these components outside markdown files, you must manually register them in your Nuxt app. Check out the Nuxt - Custom Components Directories documentation for more information on how to do so.",{"id":1853,"title":35,"titles":1854,"content":1855,"level":371},"/docs/getting-started/migration#types",[20,1841],"import type { NavItem } from '@nuxt/content/dist/runtime/types' is replaced with import type { ContentNavigationItem } from '@nuxt/content'",{"id":1857,"title":1858,"titles":1859,"content":1860,"level":371},"/docs/getting-started/migration#general","General",[20,1841],"_dir.yml files are renamed to .navigation.ymlThere is no source option in module options, instead you can define multiple sources for your collections in content.config.ts.Document ._path is now renamed to .path, likewise all internal fields with _ prefix are removed or renamed.useContentHelpers() is removedModule does not ignore dot files by default, you can ignore them by adding ignore: ['**/.*'] in exclude options of your collection source.",{"id":1862,"title":1863,"titles":1864,"content":1865,"level":371},"/docs/getting-started/migration#nuxt-studio-integration","Nuxt Studio integration",[20,1841],"The studio module has been deprecated and a new generic Preview API has been implemented directly into Nuxt Content, you can remove the @nuxthq/studio package from your dependencies and from the nuxt.config.ts modules. Instead we just need to enable the preview mode in the Nuxt configuration file by binding the Studio API. export default defineNuxtConfig({\n  content: {\n    preview: {\n      api: 'https://api.nuxt.studio'\n    }\n  },\n}) In order to keep the app config file updatable from Studio we just need to update the helper import of the nuxt.schema.ts file from @nuxthq/studio/theme to @nuxt/content/preview.",{"id":1867,"title":1868,"titles":1869,"content":1870,"level":303},"/docs/getting-started/migration#implement-document-driven-mode-in-v3","Implement Document Driven mode in v3",[20],"Implementing document driven mode in Content v3 is quite easy. All you need is to create a catch-all page in Nuxt and fetch contents based on route path. \u003Cscript lang=\"ts\" setup>\nconst route = useRoute()\nconst { data: page } = await useAsyncData(route.path, () => {\n  return queryCollection('content').path(route.path).first()\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cheader>\u003C!-- ... -->\u003C/header>\n\n    \u003CContentRenderer v-if=\"page\" :value=\"page\" />\n\n    \u003Cfooter>\u003C!-- ... -->\u003C/footer>\n  \u003C/div>\n\u003C/template>",{"id":1872,"title":1873,"titles":1874,"content":1875,"level":303},"/docs/getting-started/migration#converting-querycontent-to-querycollections","Converting queryContent to queryCollections",[20],"As we mentioned above, queryContent is dropped in favor of new collection based queryCollection. There are two main differences between these two: queryCollection is building a query for an SQL database.queryCollection does the search only inside the specified collection. You should know the collection's name (key on config). // Content v2\nconst v2Query = await queryContent(route.path).findOne()\n// Content v3 - don't forget to create `content` collection in `content.config.ts`\nconst v3Query = await queryCollection('content').path(route.path).first() // Content v2\nconst v2Query = await queryContent()\n  .where({ path: /^\\/hello\\/.*/ })\n  .find()\n// Content v3 - don't forget to create `content` collection in `content.config.ts`\nconst v3Query = await queryCollection('content')\n  .where('path', 'LIKE', '/hello%')\n  .first() Check the dedicated section for more info about collections",{"id":1877,"title":1878,"titles":1879,"content":1880,"level":303},"/docs/getting-started/migration#convert-querycontentfindsurround","Convert queryContent().findSurround()",[20],"Surround now has its own separate API. const targetPath = '/docs'\n\n// Content v2\nconst v2Surround = await queryContent(targetPath)\n  .only(['title', 'description', 'navigation'])\n  .findSurround(withoutTrailingSlash(route.path))\n\n// Content v3 - don't forget to create `content` collection in `content.config.ts`\nconst v3Surround = await queryCollectionItemSurroundings(\n  'content',\n  targetPath,\n  {\n    fields: ['title', 'description', 'navigation']\n  }\n) Check the dedicated section for more information about the",{"id":1882,"title":1883,"titles":1884,"content":1885,"level":303},"/docs/getting-started/migration#consolidate-prosepre-prosecode-and-prosecodeinline-components","Consolidate ProsePre, ProseCode, and ProseCodeInline components",[20],"Many ProsePre components are thin wrappers around the ProseCode component. We've consolidated these three components into two components. There is now no difference between ProsePre and multi-line code blocks. MDC will now map and parse single backticks ` as ProseCode instead of ProseCodeInline.MDC will now map and parse block code starting with three backticks``` as ProsePre component. Suggested Changes: Your current ProseCode logic should be moved to ProsePreRename your ProseCodeInline components to ProseCode",{"id":1887,"title":1888,"titles":1889,"content":1890,"level":303},"/docs/getting-started/migration#_diryml-files-are-renamed-to-navigationyml","_dir.yml files are renamed to .navigation.yml",[20],"In Content v3, we renamed _dir.yml to .navigation.yml. The new name better reflects the purpose of these files.\nModule uses these files to gather information about directories for generating navigation. Note that in order to make these files available for Module, youe should define your collection's source in\na way that includes these files. For example source: '**' and source: '**/*.{md|yml} will include these files\nin collection, but source: '**/*.md' will not include them.",{"id":1892,"title":1893,"titles":1894,"content":1895,"level":303},"/docs/getting-started/migration#ignore-dot-files","Ignore dot files",[20],"By default, Content v3 does not ignore dot files. If you want to ignore them, you can add ignore: ['**/.*'] in the exclude option of your collection source. defineCollection({\n  source: {\n    include: '**',\n    exclude: ['**/.*']\n  }\n}) Note that the above pattern will also excldue .navigation.yml file from collection. If you use .navigation.yml and want to keep them\nyou can use **/.(!(navigation.yml)) patter to exclude all dot files except .navigation.yml. defineCollection({\n  source: {\n    include: '**',\n    exclude: ['**/.!(navigation.yml)']\n  }\n}) html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .syuKq, html code.shiki .syuKq{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"id":32,"title":1897,"titles":1898,"content":1899,"level":270},"Define Content Collections",[],"Learn how to define and configure content collections in your Nuxt application. The Nuxt Content module automatically parses any content files within the content/ directory located at the root of your Nuxt application. This setup allows you to freely structure the folder to suit your project's needs. For better organization, consider using Content Collections, which let you categorize and manage content more effectively. These collections are defined in a content.config.ts file. If no content.config.ts file is present, all files within the content folder are parsed and imported by default. However, once a config file is added, only files matching the specified path patterns defined in collections will be imported.",{"id":1901,"title":1902,"titles":1903,"content":1904,"level":303},"/docs/collections/define#what-are-content-collections","What are Content Collections?",[1897],"Content Collections organize related items within your Nuxt Content project. They provide a structured way to manage your content, making it easier to query, display, and maintain your site's data. Key features include: Logical Grouping: Group similar content together, such as blog posts, product pages, or documentation articlesShared Configuration: Apply common settings and validations across all items within a collectionImproved Querying: Fetch and filter related content items efficientlyAutomatic Type Inference: Get type safety and autocompletion in your development environmentFlexible Structure: Organize collections by content type, category, or any other logical grouping that suits your needs",{"id":1906,"title":1907,"titles":1908,"content":1909,"level":303},"/docs/collections/define#defining-collections","Defining Collections",[1897],"Create a content.config.ts file in your project's root directory. This special file configures your collections database, utility types, and content handling. Here's a basic example: import { defineCollection, defineContentConfig } from '@nuxt/content'\n\nexport default defineContentConfig({\n  collections: {\n    docs: defineCollection({\n      // Load every file inside the `content` directory\n      source: '**',\n      // Specify the type of content in this collection\n      type: 'page'\n    })\n  }\n}) Currently, a document is designed to be present in only one collection at a time. If a file is referenced in multiple collections, live reload will not work correctly. To avoid this, it is recommended to use the exclude attribute to explicitly exclude a document from other collections using appropriate regex patterns.This topic is still under discussion in this issue: nuxt/content#2966.",{"id":1911,"title":1912,"titles":1913,"content":1914,"level":371},"/docs/collections/define#collection-schema","Collection Schema",[1897,1907],"Schemas enforce data consistency within a collection and serve as the source of truth for TypeScript types. On top of the built-in fields, you can define a schema by adding the schema property to your collection by using a zod schema: import { defineCollection, defineContentConfig, z } from '@nuxt/content'\n\nexport default defineContentConfig({\n  collections: {\n    blog: defineCollection({\n      source: 'blog/*.md',\n      type: 'page',\n      // Define custom schema for docs collection\n      schema: z.object({\n        tags: z.array(z.string()),\n        image: z.string(),\n        date: z.date()\n      })\n    })\n  }\n}) @nuxt/content exposes a z object that contains a set of Zod schemas for common data types. Check the Zod’s README for complete documentation on how Zod works and what features are available. You can define as many collections as you want to organize different types of content.",{"id":1916,"title":1917,"titles":1918,"content":1919,"level":303},"/docs/collections/define#querying-collections","Querying Collections",[1897],"Use the queryCollection util to fetch one or all items from a collection: \u003Cscript setup lang=\"ts\">\nconst { data: posts } = await useAsyncData('blog', () => queryCollection('blog').all())\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Ch1>Blog\u003C/h1>\n    \u003Cul>\n      \u003Cli v-for=\"post in posts\" :key=\"post.id\">\n        \u003CNuxtLink :to=\"post.path\">{{ post.title }}\u003C/NuxtLink>\n      \u003C/li>\n    \u003C/ul>\n  \u003C/div>\n\u003C/template> Learn more about the available query options in our queryCollections API documentation.",{"id":1921,"title":1922,"titles":1923,"content":1924,"level":303},"/docs/collections/define#definecollection","defineCollection()",[1897],"The defineCollection function defines a collection in your content configuration. Here's its TypeScript signature: function defineCollection(collection: Collection): DefinedCollection\n\ntype Collection = {\n  // Determines how content is processed\n  type: 'page' | 'data'\n  // Specifies content location\n  source?: string | CollectionSource\n  // Zod schema for content validation and typing\n  schema?: ZodObject\u003CT>\n} Learn more about collection types. type CollectionSource = {\n  // Glob pattern for content matching\n  include: string\n  // .path prefix (only applies to 'page' type)\n  prefix?: string\n  // Glob patterns to exclude content\n  exclude?: string[]\n  // Root directory for content matching\n  cwd?: string\n  // Remote git repository URL (e.g., https://github.com/nuxt/content)\n  repository?: string\n  // Authentication token for private repositories (e.g., GitHub personal access token)\n  authToken?: string\n} Learn more about collection sources. The function returns the defined collection object. html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .syuKq, html code.shiki .syuKq{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sK9QF, html code.shiki .sK9QF{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"id":36,"title":1926,"titles":1927,"content":1928,"level":270},"Collection Types",[],"Learn about the two types of collections you can define in Nuxt Content. In Nuxt Content, you can specify a type for each collection, depending on the intended purpose of the collection files. Collections can be defined as either page or data types. For both types, built-in fields are generated. Every collection includes these default fields: id: Unique content identifierstem: File path without extension (used for sorting and location)extension: File extensionmeta: Custom fields not defined in the collection schema",{"id":1930,"title":1931,"titles":1932,"content":1933,"level":303},"/docs/collections/types#page-type","Page type",[1926],"defineCollection({\n  source: '**/*.md',\n  type: 'page'\n}) Use the page type if there is a 1-to-1 relationship between content files and pages on your site.",{"id":1935,"title":1936,"titles":1937,"content":1938,"level":371},"/docs/collections/types#path-generation","Path generation",[1926,1931],"Nuxt Content will automatically generate a path for each file in the collection, making it easy to create URL mappings. Here are examples of generated paths based on file structure: FilePathcontent/index.md/content/about.md/aboutcontent/blog/index.md/blogcontent/blog/hello.md/blog/hellocontent/1.guide/2.installation/guide/installation You can use the helper queryCollection('COLLECTION').path('PATH') to retrieve content by a specific path.",{"id":1940,"title":1941,"titles":1942,"content":1943,"level":371},"/docs/collections/types#schema-overrides","Schema Overrides",[1926,1931],"When you use the page type, Nuxt Content generates several standard fields that are commonly used for web pages. These fields provide structure and are automatically applied to the collection’s schema: path: Generated route pathtitle: Page titledescription: Page descriptionseo: SEO metadata (to be used with Nuxt's useSeoMeta composable)body: Page content parsed as ASTnavigation: Page navigation configuration (for queryCollectionNavigation) Here is the corresponding schema applied: path: z.string(),\n  title: z.string(),\n  description: z.string(),\n  seo: z.intersection(\n    z.object({\n      title: z.string().optional(),\n      description: z.string().optional(),\n      meta: z.array(z.record(z.string(), z.any())).optional(),\n      link: z.array(z.record(z.string(), z.any())).optional(),\n    }),\n    z.record(z.string(), z.any()),\n  ).optional().default({}),\n  body: z.object({\n    type: z.string(),\n    children: z.any(),\n    toc: z.any(),\n  }),\n  navigation: z.union([\n    z.boolean(),\n    z.object({\n      title: z.string(),\n      description: z.string(),\n      icon: z.string(),\n    }),\n  ]).default(true), You can override any of these fields by defining them in the collection’s schema.",{"id":1945,"title":1946,"titles":1947,"content":1948,"level":303},"/docs/collections/types#data-type","Data type",[1926],"defineCollection({\n  source: 'authors/**.yml',\n  type: 'data'\n}) The data type is useful for content that doesn’t directly correspond to a webpage but instead represents structured data you might want to query and display within your application. With data collections, you have complete control over the schema, allowing you to define custom structures. There’s no strict relationship between collection type and file extension. For instance, a page collection can use Markdown or YAML or JSON files, and data collections can use any of these formats as well.",{"id":1950,"title":1951,"titles":1952,"content":1953,"level":303},"/docs/collections/types#ordering-files","Ordering Files",[1926],"For both types, you may want to control the display order in lists. Use numeric prefixes in file and directory names to specify an order. Nuxt Content will use these numbers when ordering content lists. content/\n  1.frameworks/\n    1.vue.md\n    2.nuxt.md\n  2.examples/\n    1.vercel.md\n    2.netlify.md\n    3.heroku.md\n    index.md Separate number from file name using . character. Using any other separator will not work. html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sPKOg, html code.shiki .sPKOg{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"id":40,"title":1955,"titles":1956,"content":1957,"level":270},"Collection Sources",[],"Learn how to import your files in Nuxt Content collections. Nuxt Content provides several ways to import content files into your collection. You can configure the source by using the source property within defineCollection: import { defineCollection, defineContentConfig } from '@nuxt/content'\n\nexport default defineContentConfig({\n  collections: {\n    docs: defineCollection({\n      source: '**',\n      type: 'page'\n    })\n  }\n})",{"id":1959,"title":1960,"titles":1961,"content":1962,"level":303},"/docs/collections/sources#source","source",[1955],"The source property can be defined as either a string (following a glob pattern) or an object, allowing more detailed source configuration for your target directory and files within the content folder. Example: source: '** includes all files within the content directory and its subdirectories.source: '**/*.md'includes all Markdown files within the content directory and its subdirectories.source: 'docs/**/*.yml' includes all YML files within the content/docs and its subdirectories.source: '**/*.{json,yml}' includes JSON or YML file within the content directory and all its subdirectories.source: '*.json' includes only JSON files located directly within the content directory, excluding any subdirectories.",{"id":1964,"title":1965,"titles":1966,"content":1967,"level":371},"/docs/collections/sources#include","include",[1955,1960],"Glob pattern of your target repository and files in the content folder.",{"id":1969,"title":1970,"titles":1971,"content":1972,"level":371},"/docs/collections/sources#exclude","exclude",[1955,1960],"Glob patterns to exclude content from the import.",{"id":1974,"title":1975,"titles":1976,"content":1977,"level":371},"/docs/collections/sources#prefix","prefix",[1955,1960],"This configuration only applied for page type with 1-to-1 relationship between content files and pages on your site. It represents the path prefix (base URL) of the corresponding page on the website. The prefix must start by a leading /. By default, module extracts the static prefix of source(or source.include) and uses it as a prefix for content paths. For example, if you define /en/** source, module will auto-fill the prefix with /en. You can manually provide a prefix to override this behavior. The prefix can be removed by setting prefix: '/' in the collection source. defineCollection({\n  type: \"page\",\n  source: {\n    include: \"en/**\",\n    exclude: [\"en/index.md\"],\n    prefix: '/'\n  }\n})",{"id":1979,"title":1980,"titles":1981,"content":1982,"level":371},"/docs/collections/sources#cwd","cwd",[1955,1960],"Root directory for content matching. Example: If you want to include files from a folder outside the content directory, set the absolute path of that folder to the cwd property. source: {\n  cwd: path.resolve('packages/my-pkg/docs'),\n  include: '**/*.md',\n}",{"id":1984,"title":1985,"titles":1986,"content":1987,"level":371},"/docs/collections/sources#repository","repository",[1955,1960],"External source representing a remote git repository URL (e.g., https://github.com/nuxt/content)",{"id":1989,"title":1990,"titles":1991,"content":1992,"level":371},"/docs/collections/sources#authtoken","authToken",[1955,1960],"Authentication token for private repositories (e.g., GitHub personal access token). html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"id":51,"title":50,"titles":1994,"content":1995,"level":270},[],"Create and query Markdown files in your Nuxt applications and use the MDC syntax to integrate Vue components.",{"id":1997,"title":1998,"titles":1999,"content":263,"level":303},"/docs/files/markdown#usage","Usage",[50],{"id":2001,"title":2002,"titles":2003,"content":2004,"level":371},"/docs/files/markdown#define-a-collection","Define a Collection",[50,1998],"import { defineCollection, defineContentConfig, z } from '@nuxt/content'\n\nexport default defineContentConfig({\n  collections: {\n    blog: defineCollection({\n      type: 'page',\n      source: 'blog/*.md',\n      schema: z.object({\n        date: z.string()\n      })\n    })\n  }\n}) Learn more about the page collection type.",{"id":2006,"title":2007,"titles":2008,"content":2009,"level":371},"/docs/files/markdown#create-md-files","Create .md files",[50,1998],"Create blog posts in content/blog/ directory. ---\ndate: 2020-11-11\n---\n\n# Foo\n\nThis is Foo blog post.\n---\ndate: 2024-12-12\n---\nHello\nI am bar. Nice to meet you.",{"id":2011,"title":2012,"titles":2013,"content":2014,"level":371},"/docs/files/markdown#query-markdown-files","Query Markdown Files",[50,1998],"Now we can query blog posts: // Get the foo post\nconst fooPost = await queryCollection('blog').path('/foo').first()\n\n// Find all posts\nconst allPosts = await queryCollection('blog').order('date', 'DESC').all()",{"id":2016,"title":2017,"titles":2018,"content":2019,"level":371},"/docs/files/markdown#display-markdown","Display Markdown",[50,1998],"To display the content of a markdown file, you can use the \u003CContentRenderer> component. \u003Cscript setup>\nconst slug = useRoute().params.slug\nconst { data: post } = await useAsyncData(`blog-${slug}`, () => {\n  return queryCollection('blog').path(`/blog/${slug}`).first()\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003C!-- Render the blog post as Prose & Vue components -->\n  \u003CContentRenderer :value=\"post\" />\n\u003C/template> Read more about the \u003CContentRenderer> component and Prose Components.",{"id":2021,"title":2022,"titles":2023,"content":2024,"level":303},"/docs/files/markdown#frontmatter","Frontmatter",[50],"Frontmatter is a convention of Markdown-based CMS to provide meta-data to pages, like description or title. In Nuxt Content, the frontmatter uses the YAML syntax with key: value pairs. These data are available when rendering the content and can store any information that you would need.",{"id":2026,"title":2027,"titles":2028,"content":2029,"level":371},"/docs/files/markdown#syntax","Syntax",[50,2022],"You can declare a frontmatter block at the top of the Markdown files in the content/ directory with the --- identifier. ---\ntitle: 'Title of the page'\ndescription: 'meta description of the page'\n---\n\n\u003C!-- Content of the page --> const home = await queryCollection('content').path('/').first()\n\nconsole.log(home.title)\n// => 'Title of the page'\nconsole.log(home.description)\n// => 'meta description of the page'\nconsole.log(home.body)\n// => AST object of the page content",{"id":2031,"title":2032,"titles":2033,"content":2034,"level":371},"/docs/files/markdown#native-parameters","Native parameters",[50,2022],"KeyTypeDefaultDescriptiontitlestringFirst \u003Ch1> of the pageTitle of the page, will also be injected in metasdescriptionstringFirst \u003Cp> of the pageDescription of the page, will be shown below the title and injected into the metasnavigationbooleantrueDefine if the page is included in queryCollectionNavigation return value.",{"id":2036,"title":2037,"titles":2038,"content":2039,"level":303},"/docs/files/markdown#mdc-syntax","MDC Syntax",[50],"We created the MDC syntax to supercharge Markdown and give you the ability to integrate Vue components with slots and props inside your Markdown. Install the MDC VS Code extension to get proper syntax highlighting for the MDC syntax.",{"id":2041,"title":2042,"titles":2043,"content":2044,"level":303},"/docs/files/markdown#vue-components","Vue Components",[50],"You can use any Vue component in your Markdown files. We have a special syntax to make it easier to use components in your Markdown files. ::component-name\nDefault slot content\n:: Components that are used in Markdown has to be marked as global in your Nuxt app if you don't use the components/content/ directory, visit Nuxt 3 docs to learn more about it.",{"id":2046,"title":2047,"titles":2048,"content":2049,"level":371},"/docs/files/markdown#block-components","Block Components",[50,2042],"Block components are components that accept Markdown content or another component as a slot. The component must contain at least one \u003Cslot /> component to accept formatted text. In a markdown file, use the component with the :: identifier. ::card\nThe content of the card\n::\n\u003C!-- components/content/Card.vue -->\n\u003Ctemplate>\n  \u003Cdiv class=\"p-2 border bg-white dark:bg-black dark:border-gray-700 rounded\">\n    \u003Cslot />\n  \u003C/div>\n\u003C/template>\nThe content of the card",{"id":2051,"title":2052,"titles":2053,"content":2054,"level":371},"/docs/files/markdown#slots","Slots",[50,2042],"A component's slots can accept content or another components. Default slot renders the top-level content inside the block component or with #defaultNamed slots use the # identifier to render the corresponding content. ::hero\nMy Page Title\n\n#description\nThis will be rendered inside the `description` slot.\n::\n\u003Ctemplate>\n  \u003Csection>\n    \u003Ch1 class=\"text-4xl\">\n      \u003Cslot mdc-unwrap=\"p\" />\n    \u003C/h1>\n    \u003Cslot name=\"description\" />\n  \u003C/section>\n\u003C/template>\nMy Page TitleThis will be rendered inside the description slot. Read more about the \u003Cslot /> component. You can use Markdown inside your components slots:::the-title\nA [rich text](/) will be **rendered** by the component.\n::\n\u003Ctemplate>\n  \u003Ch1 class=\"text-4xl\">\n    \u003Cslot mdc-unwrap=\"p\" />\n  \u003C/h1>\n\u003C/template>\nA rich text will be rendered by the component.",{"id":2056,"title":2057,"titles":2058,"content":2059,"level":371},"/docs/files/markdown#props","Props",[50,2042],"There are two ways to pass props to components using MDC.",{"id":2061,"title":2062,"titles":2063,"content":2064,"level":421},"/docs/files/markdown#inline-method","Inline method",[50,2042,2057],"The {} identifier passes props to components in a terse way by using a key=value syntax. ::alert{type=\"warning\"}\nThe **alert** component.\n::\n\u003Cscript setup>\ndefineProps(['type'])\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv :class=\"[type]\">\n    \u003Cslot mdc-unwrap=\"p\" />\n  \u003C/div>\n\u003C/template>\nThe alert component. Multiple props can be separated with a space: ::alert{type=\"warning\" icon=\"exclamation-circle\"}\nOops! An error occurred\n:: The v-bind shorthand : can be also be used to bind a prop to a value in the frontmatter. ---\ntype: \"warning\"\n---\n\n::alert{:type=\"type\"}\nYour warning\n:: If you want to pass arrays or objects as props to components you can pass them as JSON string and prefix the prop key with a colon to automatically decode the JSON string. Note that in this case you should use single quotes for the value string so you can use double quotes to pass a valid JSON string: ::dropdown{:items='[\"Nuxt\", \"Vue\", \"React\"]'}\n::\n::dropdown{:items='[1,2,3.5]'}\n::\n::chart{:options='{\"responsive\": true, \"scales\": {\"y\": {\"beginAtZero\": true}}}'}\n::",{"id":2066,"title":2067,"titles":2068,"content":2069,"level":421},"/docs/files/markdown#yaml-method","YAML method",[50,2042,2057],"The YAML method uses the --- identifier to declare one prop per line, that can be useful for readability. ::icon-card\n---\nicon: IconNuxt\ndescription: Harness the full power of Nuxt and the Nuxt ecosystem.\ntitle: Nuxt Architecture.\n---\n::\n\u003Cscript setup>\ndefineProps({\n  title: {\n    type: String,\n    default: 'Default title'\n  },\n  description: {\n    type: String,\n    default: 'Default description'\n  },\n  icon: {\n    type: String,\n    default: 'IconMarkdown'\n  }\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"p-6 border bg-white dark:bg-black dark:border-gray-700 rounded\">\n    \u003Ccomponent :is=\"icon\" class=\"w-20 h-20\" />\n    \u003Ch2 class=\"text-3xl font-semibold mb-2\">\n      {{ title }}\n    \u003C/h2>\n    \u003Cp>{{ description }}\u003C/p>\n  \u003C/div>\n\u003C/template>",{"id":2071,"title":2072,"titles":2073,"content":2074,"level":371},"/docs/files/markdown#attributes","Attributes",[50,2042],"Attributes are useful for highlighting and modifying part of paragraph. The syntax is nearly similar to inline components and markdown links syntax. Possible values are all named attributes, classes with the notation .class-name and an ID with #id-name. Hello [World]{style=\"color: green;\" .custom-class #custom-id}!\nHello World ! In addition to mdc components and span, attribute syntax will work on images, links, inline code, *bold* and _italic_ text. Attributes work on:\n\n- ![favicon](/favicon.ico){style=\"display: inline; margin: 0;\"} image,\n- [link](#attributes){style=\"background-color: pink;\"}, `code`{style=\"color: cyan;\"},\n- _italic_{style=\"background-color: yellow; color:black;\"} and **bold**{style=\"background-color: lightgreen;\"} texts.\nAttributes work on: image,link, code,italic and bold texts.",{"id":2076,"title":2077,"titles":2078,"content":2079,"level":303},"/docs/files/markdown#binding-data-in-markdown","Binding Data in Markdown",[50],"You can bind data within your Markdown document using the {{ $doc.variable || 'defaultValue' }} syntax. These values can be defined in the YAML frontmatter at the top of the document, within each MDC component, or injected using the data prop of the \u003CContentRenderer> component.",{"id":2081,"title":2082,"titles":2083,"content":2084,"level":371},"/docs/files/markdown#example-1-define-in-yaml","Example 1: Define in YAML",[50,2077],"---\ntitle: 'Title of the page'\ndescription: 'meta description of the page'\ncustomVariable: 'Custom Value'\n---\n\n# The Title is {{ $doc.title }} and customVariable is {{ $doc.customVariable || 'defaultValue' }}",{"id":2086,"title":2087,"titles":2088,"content":2089,"level":371},"/docs/files/markdown#example-2-define-in-external-with-contentrenderer","Example 2: Define in external with \u003CContentRenderer>",[50,2077],"\u003Ctemplate>\n  \u003Cdiv>\n    \u003CContentRenderer :value=\"data\" :data=\"mdcVars\"/>\n    \u003Cbutton type=\"button\" v-on:click=\"mdcVars.name = 'Hugo'\">Change name\u003C/button>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\nconst { data } = await useAsyncData(() => queryCollection('content').path('/test').first());\nconst mdcVars = ref({ name: 'Maxime'});\n\u003C/script> # Hello {{ $doc.name || 'World' }}",{"id":2091,"title":98,"titles":2092,"content":2093,"level":303},"/docs/files/markdown#prose-components",[50],"In Nuxt Content, the prose represents HTML tags generated by the Markdown syntax, such as heading levels and links. For each HTML tag, a Vue component is used, allowing you to override them if needed, for example \u003Cp> becomes \u003CProseP>. If you want to customize a Prose component, here are the recommended steps: Check out the original component sources.Use the exact same props.In your components/content/ directory, give it the same name.Make it yours 🚀. Read the complete Prose reference in the Prose Components section.",{"id":2095,"title":2096,"titles":2097,"content":2098,"level":303},"/docs/files/markdown#code-highlighting","Code Highlighting",[50],"Nuxt Content uses Shiki, which colors tokens with VSCode themes. Code highlighting works both on ProsePre and ProseCode. Each line of a code block gets its line number in the line attribute so lines can be labeled or individually styled. Read the API reference to configure or entirely disable syntax highlighting.",{"id":2100,"title":2101,"titles":2102,"content":2103,"level":303},"/docs/files/markdown#images","Images",[50],"You can add images to your public directory: content/\n  index.md\npublic/\n  image.png\nnuxt.config.ts\npackage.json And then use them in your markdown files in the content directory as such: ![my image](/image.png)",{"id":2105,"title":2106,"titles":2107,"content":2108,"level":303},"/docs/files/markdown#excerpt","Excerpt",[50],"Content excerpt or summary can be extracted from the content using \u003C!--more--> as a divider. ---\ntitle: Introduction\n---\n\nLearn how to use `@nuxt/content`.\n\n\u003C!--more-->\n\nFull amount of content beyond the more divider. Description property will contain the excerpt content unless defined within the frontmatter props. If there is no \u003C!--more--> divider in the text then excerpt is undefined. You should define the excerpt field in the collection schema if you want to use the excerpt feature.const content = defineCollection({\n  type: 'page',\n  source: '**',\n  schema: z.object({\n    excerpt: z.object({\n      type: z.string(),\n      children: z.any(),\n    }),\n  }),\n})\nRead more about the collection schema. Example variables will be injected into the document: {\n  \"excerpt\": Object\n  \"body\": Object\n  // ... other keys\n} html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .syuKq, html code.shiki .syuKq{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sAZcy, html code.shiki .sAZcy{--shiki-light:#90A4AE;--shiki-light-text-decoration:underline;--shiki-default:#EEFFFF;--shiki-default-text-decoration:underline;--shiki-dark:#BABED8;--shiki-dark-text-decoration:underline}html pre.shiki code .slNEC, html code.shiki .slNEC{--shiki-light:#39ADB5;--shiki-light-font-weight:bold;--shiki-default:#89DDFF;--shiki-default-font-weight:bold;--shiki-dark:#89DDFF;--shiki-dark-font-weight:bold}html pre.shiki code .sf2UM, html code.shiki .sf2UM{--shiki-light:#E53935;--shiki-light-font-weight:bold;--shiki-default:#F07178;--shiki-default-font-weight:bold;--shiki-dark:#F07178;--shiki-dark-font-weight:bold}html pre.shiki code .suvBa, html code.shiki .suvBa{--shiki-light:#E53935;--shiki-light-text-decoration:underline;--shiki-default:#F07178;--shiki-default-text-decoration:underline;--shiki-dark:#F07178;--shiki-dark-text-decoration:underline}html pre.shiki code .sLSIA, html code.shiki .sLSIA{--shiki-light:#E53935;--shiki-light-font-style:italic;--shiki-default:#F07178;--shiki-default-font-style:italic;--shiki-dark:#F07178;--shiki-dark-font-style:italic}",{"id":55,"title":54,"titles":2110,"content":2111,"level":270},[],"How to define, write and query YAML data.",{"id":2113,"title":2114,"titles":2115,"content":2116,"level":303},"/docs/files/yaml#define-collection","Define Collection",[54],"import { defineCollection, defineContentConfig, z } from '@nuxt/content'\n\nexport default defineContentConfig({\n  collections: {\n    authors: defineCollection({\n      type: 'data',\n      source: 'authors/**.yml',\n      schema: z.object({\n        name: z.string(),\n        avatar: z.string(),\n        url: z.string()\n      })\n    })\n  }\n})",{"id":2118,"title":2119,"titles":2120,"content":2121,"level":303},"/docs/files/yaml#create-yml-files","Create .yml files",[54],"Create authors files in content/authors/ directory. name: Ahad Birang\navatar: https://avatars.githubusercontent.com/u/2047945?v=4\nurl: https://github.com/farnabaz\nname: Baptiste Leproux\navatar: https://avatars.githubusercontent.com/u/7290030?v=4\nurl: https://github.com/larbish",{"id":2123,"title":2124,"titles":2125,"content":2126,"level":303},"/docs/files/yaml#query-data","Query Data",[54],"Now we can query authors: \u003Cscript lang=\"ts\" setup>\n// Find a single author\nconst { data: author } = await useAsyncData('larbish', () => {\n  return queryCollection('authors')\n    .where('stem', '=', 'larbish')\n    .first()\n})\n\n// Get all authors\nconst { data: authors } = await useAsyncData('authors', () => {\n  return queryCollection('authors')\n    .order('name', 'DESC')\n    .all()\n})\n\u003C/script> html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .syuKq, html code.shiki .syuKq{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"id":59,"title":58,"titles":2128,"content":2129,"level":270},[],"How to define, write and query JSON data.",{"id":2131,"title":2114,"titles":2132,"content":2133,"level":303},"/docs/files/json#define-collection",[58],"import { defineCollection, defineContentConfig, z } from '@nuxt/content'\n\nexport default defineContentConfig({\n  collections: {\n    authors: defineCollection({\n      type: 'data',\n      source: 'authors/**.json',\n      schema: z.object({\n        name: z.string(),\n        avatar: z.string(),\n        url: z.string()\n      })\n    })\n  }\n})",{"id":2135,"title":2136,"titles":2137,"content":2138,"level":303},"/docs/files/json#create-json-files","Create .json files",[58],"Create authors files in content/authors/ directory. {\n  \"name\": \"Ahad Birang\",\n  \"avatar\": \"https://avatars.githubusercontent.com/u/2047945?v=4\",\n  \"url\": \"https://github.com/farnabaz\"\n}\n{\n  \"name\": \"Baptiste Leproux\",\n  \"avatar\": \"https://avatars.githubusercontent.com/u/7290030?v=4\",\n  \"url\": \"https://github.com/larbish\"\n} Each file in data collection should contain only one object, therefore having top level array in a JSON file will cause invalid result in query time.",{"id":2140,"title":2124,"titles":2141,"content":2126,"level":303},"/docs/files/json#query-data",[58],{"id":69,"title":68,"titles":2143,"content":2144,"level":270},[],"The queryCollection composable provides methods for querying and fetching your collections.",{"id":2146,"title":1998,"titles":2147,"content":2148,"level":303},"/docs/utils/query-collection#usage",[68],"Use the auto-imported queryCollection to find contents inside a collection. Here we assume that you have defined docs collection inside content.config.ts. If you have not defined any collection, check How to define a collection. \u003Cscript>\nconst route = useRoute()\nconst { data: page } = await useAsyncData(route.path, () => {\n  return queryCollection('docs').path(route.path).first()\n})\n\u003C/script> The queryCollection utility is available in both Vue and Nitro. Checkout Server Usage for more details on how to use it on the server side.",{"id":2150,"title":2151,"titles":2152,"content":263,"level":303},"/docs/utils/query-collection#api","API",[68],{"id":2154,"title":2155,"titles":2156,"content":2157,"level":371},"/docs/utils/query-collection#type","Type",[68,2151],"function queryCollection\u003CT extends keyof Collections>(collection: T): CollectionQueryBuilder\u003CCollections[T]>\n\ninterface CollectionQueryBuilder\u003CT> {\n  where(field: keyof T | string, operator: SQLOperator, value?: unknown): CollectionQueryBuilder\u003CT>\n  andWhere(groupFactory: QueryGroupFunction\u003CT>): CollectionQueryBuilder\u003CT>\n  orWhere(groupFactory: QueryGroupFunction\u003CT>): CollectionQueryBuilder\u003CT>\n  order(field: keyof T, direction: 'ASC' | 'DESC'): CollectionQueryBuilder\u003CT>\n  // ... other methods\n}",{"id":2159,"title":2160,"titles":2161,"content":2162,"level":371},"/docs/utils/query-collection#querycollectioncollection-collectionname","queryCollection(collection: CollectionName)",[68,2151],"Create a query builder to search in the specific collection. Parameters:collection: The key of defined collection in content.config.ts",{"id":2164,"title":2165,"titles":2166,"content":2167,"level":371},"/docs/utils/query-collection#pathpath-string","path(path: string)",[68,2151],"Search for contents that have specific path. (path is an special field in page collections which generates based on fs path and can be use as route to render the content) Parameter:path: The path string to match. const route = useRoute()\nconst { data } = await useAsyncData(route.path, () => {\n  return queryCollection('docs').path(route.path).first()\n})",{"id":2169,"title":2170,"titles":2171,"content":2172,"level":371},"/docs/utils/query-collection#selectfields-keyof-collection","select(...fields: keyof Collection)",[68,2151],"Select specific fields from the collection to be returned in the query result. Parameters:\n...fields: A list of field names to select from the collection. const route = useRoute()\nconst { data } = await useAsyncData(route.path, () => {\n  return queryCollection('docs')\n    .select('path', 'title', 'description')\n    .first()\n})",{"id":2174,"title":2175,"titles":2176,"content":2177,"level":371},"/docs/utils/query-collection#wherefield-keyof-collection-string-operator-sqloperator-value-unknown","where(field: keyof Collection | string, operator: SqlOperator, value?: unknown)",[68,2151],"Add a condition to the query to filter results based on a specific field. Parameters:\nfield: The field to filter onoperator: The SQL operator to use for comparison. Possible values include:\n'=': Equal to'>': Greater than'\u003C': Less than'\u003C>': Not equal to'IN': In a list of values'BETWEEN': Between two values'NOT BETWEEN': Not between two values'IS NULL': Is null'IS NOT NULL': Is not null'LIKE': Matches a pattern'NOT LIKE': Does not match a patternvalue: The value to compare against. The type depends on the operator used. const route = useRoute()\nconst { data } = await useAsyncData(route.path, () => {\n  return queryCollection('docs')\n    .where('date', '\u003C', '2024-04-04')\n    .all()\n})",{"id":2179,"title":2180,"titles":2181,"content":2182,"level":371},"/docs/utils/query-collection#andwheregroupfactory-querygroupfunctioncollection","andWhere(groupFactory: QueryGroupFunction\u003CCollection>)",[68,2151],"Add an AND condition group to the query. This allows for more complex query conditions. Parameter:\ngroupFactory: A function that receives a query builder and can add multiple conditions that will be grouped together with AND const { data } = await useAsyncData('recent-docs', () => {\n  return queryCollection('docs')\n    .where('published', '=', true)\n    .andWhere(query => {\n      query.where('date', '>', '2024-01-01')\n          .where('category', '=', 'news')\n    })\n    .all()\n})",{"id":2184,"title":2185,"titles":2186,"content":2187,"level":371},"/docs/utils/query-collection#orwheregroupfactory-querygroupfunctioncollection","orWhere(groupFactory: QueryGroupFunction\u003CCollection>)",[68,2151],"Add an OR condition group to the query. This allows for alternative conditions. Parameter:\ngroupFactory: A function that receives a query builder and can add multiple conditions that will be grouped together with OR const { data } = await useAsyncData('featured-docs', () => {\n  return queryCollection('docs')\n    .where('published', '=', true)\n    .orWhere(query => {\n      query.where('featured', '=', true)\n          .where('priority', '>', 5)\n    })\n    .all()\n})",{"id":2189,"title":2190,"titles":2191,"content":2192,"level":371},"/docs/utils/query-collection#orderfield-keyof-collection-direction-asc-desc","order(field: keyof Collection, direction: 'ASC' | DESC)",[68,2151],"Order the query results based on a specific field. Parameters:\nfield: The field to order by.direction: The direction of ordering, either 'ASC' for ascending or 'DESC' for descending. const route = useRoute()\nconst { data } = await useAsyncData(route.path, () => {\n  return queryCollection('docs')\n    .order('date', 'DESC')\n    .all()\n})",{"id":2194,"title":2195,"titles":2196,"content":2197,"level":371},"/docs/utils/query-collection#limitlimit-number","limit(limit: number)",[68,2151],"Limit the number of results returned by the query. Parameter:\nlimit: The maximum number of results to return. const route = useRoute()\nconst { data } = await useAsyncData(route.path, () => {\n  return queryCollection('docs')\n    .limit(10)\n    .all()\n})",{"id":2199,"title":2200,"titles":2201,"content":2202,"level":371},"/docs/utils/query-collection#skipskip-number","skip(skip: number)",[68,2151],"Skip a specified number of results in the query. Parameter:\nskip: The number of results to skip. const route = useRoute()\nconst { data } = await useAsyncData(route.path, () => {\n  return queryCollection('docs')\n    // Skip first 5 items\n    .skip(5)\n    .all()\n})",{"id":2204,"title":2205,"titles":2206,"content":2207,"level":371},"/docs/utils/query-collection#all","all()",[68,2151],"Execute the query and return all matching results. Returns: A Promise that resolves to an array of all matching documents. const route = useRoute()\nconst { data } = await useAsyncData(route.path, () => {\n  return queryCollection('docs').all()\n})",{"id":2209,"title":2210,"titles":2211,"content":2212,"level":371},"/docs/utils/query-collection#first","first()",[68,2151],"Execute the query and return the first matching result. Returns: A Promise that resolves to the first matching document, or null if no documents match. const route = useRoute()\nconst { data } = await useAsyncData(route.path, () => {\n  return queryCollection('docs').first()\n})",{"id":2214,"title":2215,"titles":2216,"content":2217,"level":303},"/docs/utils/query-collection#examples","Examples",[68],"Here is a complete example of how to fetch list of documents in docs collections. \u003Cscript setup lang=\"ts\">\nconst { data: docs } = await useAsyncData('documents-list', () => {\n  return queryCollection('docs')\n    .order('date', 'DESC')\n    .select('title', 'path', 'description')\n    .all()\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CNuxtLink v-for=\"doc in docs\" :key=\"doc.path\" :to=\"doc.path\">\n    \u003Ch2>{{ doc.title }}\u003C/h2>\n    \u003Cp>{{ doc.description }}\u003C/p>\n  \u003C/NuxtLink>\n\u003C/template>",{"id":2219,"title":2220,"titles":2221,"content":2222,"level":303},"/docs/utils/query-collection#server-usage","Server Usage",[68],"Nuxt Content provides a similar utility to query collections on the server side. The only difference is that you need to pass event as the first argument to the queryCollection function. export default eventHandler(async (event) => {\n  const { slug } = getRouterParams(event)\n  const page = await queryCollection(event, 'docs').path(slug).first()\n  return page\n}) Make sure to create server/tsconfig.json file with the following content to avoid type error.{\n  \"extends\": \"../.nuxt/tsconfig.server.json\"\n} html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sK9QF, html code.shiki .sK9QF{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .syuKq, html code.shiki .syuKq{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sPKOg, html code.shiki .sPKOg{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .smPcV, html code.shiki .smPcV{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"id":73,"title":72,"titles":2224,"content":2225,"level":270},[],"The queryCollectionNavigation composable generates the navigation tree of given collection.",{"id":2227,"title":2155,"titles":2228,"content":2229,"level":303},"/docs/utils/query-collection-navigation#type",[72],"function queryCollectionNavigation\u003CT extends keyof PageCollections>(\n  collection: T,\n  fields?: Array\u003Ckeyof PageCollections[T]>\n): ChainablePromise\u003CT, ContentNavigationItem[]>\n\ninterface ChainablePromise\u003CT extends keyof PageCollections, R> extends Promise\u003CR> {\n  where(field: keyof PageCollections[T] | string, operator: SQLOperator, value?: unknown): ChainablePromise\u003CT, R>\n  andWhere(groupFactory: QueryGroupFunction\u003CPageCollections[T]>): ChainablePromise\u003CT, R>\n  orWhere(groupFactory: QueryGroupFunction\u003CPageCollections[T]>): ChainablePromise\u003CT, R>\n  order(field: keyof PageCollections[T], direction: 'ASC' | 'DESC'): ChainablePromise\u003CT, R>\n}",{"id":2231,"title":1998,"titles":2232,"content":2233,"level":303},"/docs/utils/query-collection-navigation#usage",[72],"Use the auto-imported queryCollectionNavigation to generate a navigation tree for a specific collection. This is particularly useful for creating dynamic navigation menus or sidebars based on your content structure. The function returns a chainable promise that allows you to add additional query conditions: \u003Cscript setup lang=\"ts\">\nconst { data } = await useAsyncData('navigation', () => {\n  return queryCollectionNavigation('docs')\n    .where('published', '=', true)\n    .order('date', 'DESC')\n})\n\u003C/script> The queryCollectionNavigation utility is available in both Vue and Nitro. Checkout Server Usage for more details on how to use it on the server side.",{"id":2235,"title":2236,"titles":2237,"content":2238,"level":371},"/docs/utils/query-collection-navigation#navigation-metadata-with-navigationyml","Navigation metadata with .navigation.yml",[72,1998],"You can add metadata to a directory using a .navigation.yml file. title: Getting Started\nicon: i-lucide-square-play",{"id":2240,"title":2151,"titles":2241,"content":263,"level":303},"/docs/utils/query-collection-navigation#api",[72],{"id":2243,"title":2244,"titles":2245,"content":2246,"level":371},"/docs/utils/query-collection-navigation#querycollectionnavigationcollection-collectionname-extrafield-keyof-collection","queryCollectionNavigation(collection: CollectionName, extraField: keyof Collection)",[72,2151],"Generate a navigation tree for the specified collection. Parameters:\ncollection: The key of the defined collection in content.config.ts.extraFields: (Optional) An array of additional fields to include in the navigation items. (By default title and path are included in the navigation items.)Returns: A chainable promise that resolves to a navigation tree structure. The promise includes methods for adding query conditions:\nwhere(field, operator, value): Add a WHERE conditionandWhere(groupFactory): Add a grouped AND conditionorWhere(groupFactory): Add a grouped OR conditionorder(field, direction): Add an ORDER BY clause The navigation tree is generated based on the directory structure and ordering happens based on files ordering",{"id":2248,"title":2215,"titles":2249,"content":2250,"level":303},"/docs/utils/query-collection-navigation#examples",[72],"Basic usage without additional query conditions: \u003Cscript setup lang=\"ts\">\nconst { data } = await useAsyncData('navigation', () => {\n  return queryCollectionNavigation('docs')\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cnav>\n    \u003Cul v-if=\"data\">\n      \u003Cli v-for=\"item in data\" :key=\"item.path\">\n        \u003CNuxtLink :to=\"item.path\">{{ item.title }}\u003C/NuxtLink>\n      \u003C/li>\n    \u003C/ul>\n  \u003C/nav>\n\u003C/template> Example with additional query conditions and extra fields: \u003Cscript setup lang=\"ts\">\nconst { data } = await useAsyncData('navigation', () => {\n  return queryCollectionNavigation('docs', ['description', 'badge'])\n    .where('draft', '=', false)\n    .where('partial', '=', false)\n    .order('title', 'ASC')\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cnav>\n    \u003Cul v-if=\"data\">\n      \u003Cli v-for=\"item in data\" :key=\"item.path\">\n        \u003CNuxtLink :to=\"item.path\">\n          {{ item.title }}\n          \u003Cspan v-if=\"item.badge\" class=\"badge\">{{ item.badge }}\u003C/span>\n        \u003C/NuxtLink>\n        \u003Cp v-if=\"item.description\">{{ item.description }}\u003C/p>\n      \u003C/li>\n    \u003C/ul>\n  \u003C/nav>\n\u003C/template>",{"id":2252,"title":2220,"titles":2253,"content":2254,"level":303},"/docs/utils/query-collection-navigation#server-usage",[72],"Nuxt Content provides a similar utility to query collections on the server side. The only difference is that you need to pass event as the first argument to the queryCollectionNavigation function. export default eventHandler(async (event) => {\n  const navigation = await queryCollectionNavigation(event, 'docs')\n  return navigation\n}) Make sure to create server/tsconfig.json file with the following content to avoid type error.{\n  \"extends\": \"../.nuxt/tsconfig.server.json\"\n} html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sK9QF, html code.shiki .sK9QF{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sPKOg, html code.shiki .sPKOg{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"id":77,"title":76,"titles":2256,"content":2257,"level":270},[],"The queryCollectionItemSurroundings composable looks for sibling contents of an specific path.",{"id":2259,"title":2155,"titles":2260,"content":2261,"level":303},"/docs/utils/query-collection-item-surroundings#type",[76],"function queryCollectionItemSurroundings\u003CT extends keyof PageCollections>(\n  collection: T,\n  path: string,\n  opts?: SurroundOptions\u003Ckeyof PageCollections[T]>\n): ChainablePromise\u003CT, ContentNavigationItem[]>\n\ninterface ChainablePromise\u003CT extends keyof PageCollections, R> extends Promise\u003CR> {\n  where(field: keyof PageCollections[T] | string, operator: SQLOperator, value?: unknown): ChainablePromise\u003CT, R>\n  andWhere(groupFactory: QueryGroupFunction\u003CPageCollections[T]>): ChainablePromise\u003CT, R>\n  orWhere(groupFactory: QueryGroupFunction\u003CPageCollections[T]>): ChainablePromise\u003CT, R>\n  order(field: keyof PageCollections[T], direction: 'ASC' | 'DESC'): ChainablePromise\u003CT, R>\n}",{"id":2263,"title":1998,"titles":2264,"content":2265,"level":303},"/docs/utils/query-collection-item-surroundings#usage",[76],"Use the auto-imported queryCollectionItemSurroundings to find the previous and next items relative to a specific content item in a collection. This is particularly useful for creating navigation between related content pages. The function returns a chainable promise that allows you to add additional query conditions: \u003Cscript setup lang=\"ts\">\nconst { data } = await useAsyncData('surround', () => {\n  return queryCollectionItemSurroundings('docs', '/foo')\n    .where('published', '=', true)\n    .order('date', 'DESC')\n})\n\u003C/script> The queryCollectionItemSurroundings utility is available in both Vue and Nitro. Checkout Server Usage for more details on how to use it on the server side.",{"id":2267,"title":2151,"titles":2268,"content":263,"level":303},"/docs/utils/query-collection-item-surroundings#api",[76],{"id":2270,"title":2271,"titles":2272,"content":2273,"level":371},"/docs/utils/query-collection-item-surroundings#querycollectionitemsurroundingscollection-collectionname-path-string-opts-surroundoptions","queryCollectionItemSurroundings(collection: CollectionName, path: string, opts?: SurroundOptions)",[76,2151],"Find the surrounding items (previous and next) for a specific content item in a collection. Parameters:\ncollection: The key of the defined collection in content.config.ts.path: The path of the current content item.opts: (Optional) An object with the following properties:\nbefore: (Optional) The number of items to fetch before the current item. Default is 1.after: (Optional) The number of items to fetch after the current item. Default is 1.fields: (Optional) An array of additional fields to include in the surrounding items.Returns: A chainable promise that resolves to an array containing the surrounding items. The promise includes methods for adding query conditions:\nwhere(field, operator, value): Add a WHERE conditionandWhere(groupFactory): Add a grouped AND conditionorWhere(groupFactory): Add a grouped OR conditionorder(field, direction): Add an ORDER BY clause The final result will be an array with the following structure: [previousItem, nextItem] if using default options[...previousItems, ...nextItems] if using custom before and after values Each item in the array is of type ContentNavigationItem or null if there is no item in that position.",{"id":2275,"title":2215,"titles":2276,"content":2277,"level":303},"/docs/utils/query-collection-item-surroundings#examples",[76],"Basic usage without additional query conditions: \u003Cscript setup lang=\"ts\">\nconst { data } = await useAsyncData('surround', () => {\n  return queryCollectionItemSurroundings('docs', '/foo')\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"flex justify-between\">\n    \u003CNuxtLink v-if=\"data?.[0]\" :to=\"data[0].path\">\n      ← {{ data[0].title }}\n    \u003C/NuxtLink>\n    \u003CNuxtLink v-if=\"data?.[1]\" :to=\"data[1].path\">\n      {{ data[1].title }} →\n    \u003C/NuxtLink>\n  \u003C/div>\n\u003C/template> Example with additional query conditions: \u003Cscript setup lang=\"ts\">\nconst { data } = await useAsyncData('surround', () => {\n  return queryCollectionItemSurroundings('docs', '/foo', {\n    before: 1,\n    after: 1,\n    fields: ['badge', 'description']\n  })\n    .where('_draft', '=', false)\n    .where('_partial', '=', false)\n    .order('date', 'DESC')\n})\n\u003C/script>",{"id":2279,"title":2220,"titles":2280,"content":2281,"level":303},"/docs/utils/query-collection-item-surroundings#server-usage",[76],"Nuxt Content provides a similar utility to query collections on the server side. The only difference is that you need to pass event as the first argument to the queryCollectionItemSurroundings function. export default eventHandler(async (event) => {\n  const surroundings = await queryCollectionItemSurroundings(event, 'docs', '/foo')\n  return surroundings\n}) Make sure to create server/tsconfig.json file with the following content to avoid type error.{\n  \"extends\": \"../.nuxt/tsconfig.server.json\"\n} html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sK9QF, html code.shiki .sK9QF{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sPKOg, html code.shiki .sPKOg{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .smPcV, html code.shiki .smPcV{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"id":81,"title":80,"titles":2283,"content":2284,"level":270},[],"The queryCollectionSearchSections composable generates searchable sections from a collection for enhanced content discovery.",{"id":2286,"title":2155,"titles":2287,"content":2288,"level":303},"/docs/utils/query-collection-search-sections#type",[80],"function queryCollectionSearchSections(collection: keyof Collections, opts?: { ignoredTags: string[] }): ChainablePromise\u003CT, Section[]>\n\ninterface ChainablePromise\u003CT extends keyof PageCollections, R> extends Promise\u003CR> {\n  where(field: keyof PageCollections[T] | string, operator: SQLOperator, value?: unknown): ChainablePromise\u003CT, R>\n  andWhere(groupFactory: QueryGroupFunction\u003CPageCollections[T]>): ChainablePromise\u003CT, R>\n  orWhere(groupFactory: QueryGroupFunction\u003CPageCollections[T]>): ChainablePromise\u003CT, R>\n  order(field: keyof PageCollections[T], direction: 'ASC' | 'DESC'): ChainablePromise\u003CT, R>\n}",{"id":2290,"title":1998,"titles":2291,"content":2292,"level":303},"/docs/utils/query-collection-search-sections#usage",[80],"Use the auto-imported queryCollectionSearchSections to generate searchable sections from a specific collection. This is particularly useful for creating advanced search functionality or content discovery features in your application. \u003Cscript>\nconst { data: sections } = await useAsyncData('search-sections', () => {\n  return queryCollectionSearchSections('docs')\n})\n\u003C/script> The queryCollectionSearchSections utility is available in both Vue and Nitro. Checkout Server Usage for more details on how to use it on the server side.",{"id":2294,"title":2151,"titles":2295,"content":263,"level":303},"/docs/utils/query-collection-search-sections#api",[80],{"id":2297,"title":2298,"titles":2299,"content":2300,"level":371},"/docs/utils/query-collection-search-sections#querycollectionsearchsectionscollection-collectionname-options-searchsectionsoptions","queryCollectionSearchSections(collection: CollectionName, options?: SearchSectionsOptions)",[80,2151],"Generate searchable sections from the specified collection. Parameters:\ncollection: The key of the defined collection in content.config.ts.options: (Optional) An object with the following properties:\nignoredTags: An array of tag names to ignore when generating sections. Default is an empty array.Returns: A Promise that resolves to an array of searchable sections. Each section is an object with the following properties:\nid: A unique identifier for the section.title: The title of the section (usually the heading text).titles: An array of parent section titles, representing the hierarchy.content: The textual content of the section.level: The heading level (1-6) of the section, where 1 is the highest level.",{"id":2302,"title":2303,"titles":2304,"content":2305,"level":303},"/docs/utils/query-collection-search-sections#example","Example",[80],"Here's an example of how to use queryCollectionSearchSections to create searchable sections from the 'docs' collection: \u003Cscript>\nconst { data: surround } = await useAsyncData('foo-surround', () => {\n  return queryCollectionSearchSections('docs', {\n    ignoredTags: ['code']\n  })\n})\n\u003C/script>",{"id":2307,"title":2220,"titles":2308,"content":2309,"level":303},"/docs/utils/query-collection-search-sections#server-usage",[80],"Nuxt Content provides a similar utility to query collections on the server side. The only difference is that you need to pass event as the first argument to the queryCollectionSearchSections function. export default eventHandler(async (event) => {\n  const sections = await queryCollectionSearchSections(event, 'docs')\n  return sections\n}) Make sure to create server/tsconfig.json file with the following content to avoid type error.{\n  \"extends\": \"../.nuxt/tsconfig.server.json\"\n} html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sK9QF, html code.shiki .sK9QF{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"id":91,"title":90,"titles":2311,"content":2312,"level":270},[],"Takes your component from an AST to a wonderful template. The \u003CContentRenderer> component renders a document coming from a query with queryCollections(). This component only works with the pages collection.",{"id":2314,"title":2057,"titles":2315,"content":2316,"level":303},"/docs/components/content-renderer#props",[90],"PropDefaultTypeDescriptionvalue{}ParsedContentThe document to render.tag'div'stringThe tag to use for the renderer element if it is used.excerptfalsebooleanWhether to render the excerpt only without the rest of the content.components{}objectThe map of custom components to use for rendering. This prop will pass to the markdown renderer and will not affect other file types.data{}object (required)A map of variables to inject into the markdown content for later use in binding variables.proseundefinedbooleanWhether or not to render Prose components instead of HTML tags.classundefinedstring or objectRoot tag to use for rendering.unwrapfalseboolean or stringTags to unwrap separated by spaces. Example: 'ul li'.",{"id":2318,"title":2319,"titles":2320,"content":2321,"level":303},"/docs/components/content-renderer#example-usage","Example Usage",[90],"\u003Cscript lang=\"ts\" setup>\nconst route = useRoute()\nconst { data: page } = await useAsyncData(route.path, () => {\n  return queryCollection('docs').path(route.path).first()\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CContentRenderer v-if=\"page\" :value=\"page\" />\n\u003C/template>",{"id":2323,"title":2324,"titles":2325,"content":2326,"level":303},"/docs/components/content-renderer#handling-missing-pages","Handling Missing Pages",[90],"If the queried content is missing, you can display a custom fallback message. \u003Cscript lang=\"ts\" setup>\nconst route = useRoute()\nconst { data: page } = await useAsyncData(route.path, () => {\n  return queryCollection('docs').path(route.path).findOne()\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Ctemplate v-if=\"page\">\n    \u003CContentRenderer :value=\"page\" />\n  \u003C/template>\n  \u003Ctemplate v-else>\n    \u003Cdiv class=\"empty-page\">\n      \u003Ch1>Page Not Found\u003C/h1>\n      \u003Cp>Oops! The content you're looking for doesn't exist.\u003C/p>\n      \u003CNuxtLink to=\"/\">Go back home\u003C/NuxtLink>\n    \u003C/div>\n  \u003C/template>\n\u003C/template>",{"id":2328,"title":2329,"titles":2330,"content":2331,"level":303},"/docs/components/content-renderer#handling-empty-pages","Handling Empty Pages",[90],"If the queried content is empty, you can display a custom fallback message. html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":95,"title":94,"titles":2333,"content":2334,"level":270},[],"The fastest way to inject Markdown into your Vue components. When you write contents and paragraphs inside a component with the MDC syntax, you can use Vue's \u003Cslot> component to render the content.",{"id":2336,"title":1998,"titles":2337,"content":2338,"level":303},"/docs/components/slot#usage",[94],"If you don't want to modify the rendered content, simply use Vue's \u003Cslot> component. \u003Ctemplate>\n  \u003Cdiv class=\"callout\">\n    \u003Cslot />\n  \u003C/div>\n\u003C/template> Now let's use it in Markdown: ::callout\nThis is a callout.\n:: The rendered HTML will be: \u003Cdiv class=\"callout\">\n  \u003Cp>This is a callout.\u003C/p>\n\u003C/div> This usage would be similar to using the native \u003Cslot> component.",{"id":2340,"title":2341,"titles":2342,"content":2343,"level":371},"/docs/components/slot#unwrapping","Unwrapping",[94,1998],"The mdc-unwrap prop allows you to remove one or multiple wrapping elements from the rendered content. This is useful when you want to extract the content nested in native Markdown syntax. Each specified tag will get removed from AST. Let's unwrap the \u003Cp> element from the previous example: \u003Ctemplate>\n  \u003Cdiv class=\"callout\">\n    \u003Cslot mdc-unwrap=\"p\" />\n  \u003C/div>\n\u003C/template> Now the rendered HTML will be: \u003Cdiv class=\"callout\">\n  This is a callout.\n\u003C/div>",{"id":2345,"title":2346,"titles":2347,"content":2348,"level":371},"/docs/components/slot#named-slots","Named Slots",[94,1998],"The name prop allows you to bind a slot by its name. This is useful when you want to render a slot that is not the default one. Let's improve our Callout component to have a title slot: \u003Ctemplate>\n  \u003Cdiv class=\"callout\">\n    \u003Ch2 v-if=\"$slots.title\">\n      \u003Cslot name=\"title\" mdc-unwrap=\"p\" />\n    \u003C/h2>\n    \u003Cslot />\n  \u003C/div>\n\u003C/template> Now let's use it in Markdown: ::callout\n#title\nPlease be careful!\n#default\nUsing MDC & Vue components is addictive.\n:: This will result into: \u003Cdiv class=\"callout\">\n  \u003Ch2>Please be careful!\u003C/h2>\n  \u003Cp>Using MDC & Vue components is addictive.\u003C/p>\n\u003C/div> When not using the title slot, the h2 element will not be rendered.",{"id":2350,"title":2057,"titles":2351,"content":2352,"level":303},"/docs/components/slot#props",[94],"mdc-unwrap: Whether to unwrap the content or not. This is useful when you want to extract the content nested in native Markdown syntax. Each specified tag will get removed from AST.\nType: boolean or stringDefault: falseExample: 'p' or 'ul li' html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"id":99,"title":98,"titles":2354,"content":2355,"level":270},[],"A list of Prose components. Prose components are replacements for HTML typography tags. Prose components provide a simple way to customize content UI. To overwrite a prose component, create a component with the same name in your project components/content/ directory (ex: components/content/ProseA.vue). Prose components are originally part of @nuxtjs/mdc.",{"id":2357,"title":2358,"titles":2359,"content":2360,"level":303},"/docs/components/prose#prosea","ProseA",[98],"[Link](/docs/components/prose)\nLink",{"id":2362,"title":2363,"titles":2364,"content":2365,"level":303},"/docs/components/prose#proseblockquote","ProseBlockquote",[98],"> Block quote\nBlock quote",{"id":2367,"title":2368,"titles":2369,"content":2370,"level":303},"/docs/components/prose#prosepre","ProsePre",[98],"```js [file.js]{2} meta-info=val\n  export default () => {\n    console.log('Code block')\n  }\n  ```\nexport default () => {\n  console.log('Code block')\n} Component properties will be: {\n  code: \"export default () => {\\n    console.log('Code block')\\n}\"\n  language: \"js\"\n  filename: \"file.js\"\n  highlights: [2]\n  meta: \"meta-info=val\"\n} Check out the highlight options for more about the syntax highlighting. If you want to use ] in the filename, you need to escape it with 2 backslashes: \\\\]. This is necessary since JS will automatically escape the backslash in a string so \\] will be resolved as ] breaking our regex.",{"id":2372,"title":2373,"titles":2374,"content":2375,"level":303},"/docs/components/prose#prosecode","ProseCode",[98],"`code`\n\n`const code: string = 'highlighted code inline'`{lang=\"ts\"}\ncodeconst code: string = 'highlighted code inline'",{"id":2377,"title":2378,"titles":2379,"content":2380,"level":303},"/docs/components/prose#proseh1","ProseH1",[98],"# H1 Heading\nH1 Heading",{"id":2382,"title":2383,"titles":2384,"content":2385,"level":303},"/docs/components/prose#proseh2","ProseH2",[98],"## H2 Heading\nH2 Heading",{"id":2387,"title":2388,"titles":2389,"content":2390,"level":303},"/docs/components/prose#proseh3","ProseH3",[98],"### H3 Heading\nH3 Heading",{"id":2392,"title":2393,"titles":2394,"content":2395,"level":303},"/docs/components/prose#proseh4","ProseH4",[98],"#### H4 Heading\nH4 Heading",{"id":2397,"title":2398,"titles":2399,"content":2400,"level":303},"/docs/components/prose#proseh5","ProseH5",[98],"##### H5 Heading\nH5 Heading",{"id":2402,"title":2403,"titles":2404,"content":2405,"level":303},"/docs/components/prose#proseh6","ProseH6",[98],"###### H6 Heading\nH6 Heading",{"id":2407,"title":2408,"titles":2409,"content":2410,"level":303},"/docs/components/prose#prosehr","ProseHr",[98],"Divider under.\n\n---\n\nDivider above.\nDivider under.Divider above.",{"id":2412,"title":2413,"titles":2414,"content":2415,"level":303},"/docs/components/prose#proseimg","ProseImg",[98],"![A Cool Image](https://nuxt.com/design-kit/icon-green.png)",{"id":2417,"title":2418,"titles":2419,"content":2420,"level":303},"/docs/components/prose#proseul","ProseUl",[98],"- Just\n- An\n- Unordered\n- List\nJustAnUnorderedList",{"id":2422,"title":2423,"titles":2424,"content":2425,"level":303},"/docs/components/prose#proseli","ProseLi",[98],"- List element\nList element",{"id":2427,"title":2428,"titles":2429,"content":2430,"level":303},"/docs/components/prose#proseol","ProseOl",[98],"1. Foo\n2. Bar\n3. Baz\nFooBarBaz",{"id":2432,"title":2433,"titles":2434,"content":2435,"level":303},"/docs/components/prose#prosep","ProseP",[98],"Just a paragraph.\nJust a paragraph.",{"id":2437,"title":2438,"titles":2439,"content":2440,"level":303},"/docs/components/prose#prosestrong","ProseStrong",[98],"**Just a strong paragraph.**\nJust a strong paragraph.",{"id":2442,"title":2443,"titles":2444,"content":2445,"level":303},"/docs/components/prose#proseem","ProseEm",[98],"_Just an italic paragraph._\nJust an italic paragraph.",{"id":2447,"title":2448,"titles":2449,"content":2450,"level":303},"/docs/components/prose#prosetable","ProseTable",[98],"| Key | Type      | Description |\n| --- | --------- | ----------- |\n| 1   | Wonderful | Table       |\n| 2   | Wonderful | Data        |\n| 3   | Wonderful | Website     |\nKeyTypeDescription1WonderfulTable2WonderfulData3WonderfulWebsite",{"id":2452,"title":2453,"titles":2454,"content":2455,"level":303},"/docs/components/prose#prosetbody","ProseTbody",[98],"Included in ProseTable example.",{"id":2457,"title":2458,"titles":2459,"content":2455,"level":303},"/docs/components/prose#prosetd","ProseTd",[98],{"id":2461,"title":2462,"titles":2463,"content":2455,"level":303},"/docs/components/prose#proseth","ProseTh",[98],{"id":2465,"title":2466,"titles":2467,"content":2455,"level":303},"/docs/components/prose#prosethead","ProseThead",[98],{"id":2469,"title":2470,"titles":2471,"content":2472,"level":303},"/docs/components/prose#prosetr","ProseTr",[98],"Included in ProseTable example. Checkout the source code for these components on GitHub. html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .suvBa, html code.shiki .suvBa{--shiki-light:#E53935;--shiki-light-text-decoration:underline;--shiki-default:#F07178;--shiki-default-text-decoration:underline;--shiki-dark:#F07178;--shiki-dark-text-decoration:underline}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s3tsu, html code.shiki .s3tsu{--shiki-light:#FF5370;--shiki-light-font-style:italic;--shiki-default:#FF9CAC;--shiki-default-font-style:italic;--shiki-dark:#FF9CAC;--shiki-dark-font-style:italic}html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sHsDI, html code.shiki .sHsDI{--shiki-light:#90A4AE90;--shiki-default:#EEFFFF90;--shiki-dark:#BABED890}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .smPcV, html code.shiki .smPcV{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sAZcy, html code.shiki .sAZcy{--shiki-light:#90A4AE;--shiki-light-text-decoration:underline;--shiki-default:#EEFFFF;--shiki-default-text-decoration:underline;--shiki-dark:#BABED8;--shiki-dark-text-decoration:underline}html pre.shiki code .slNEC, html code.shiki .slNEC{--shiki-light:#39ADB5;--shiki-light-font-weight:bold;--shiki-default:#89DDFF;--shiki-default-font-weight:bold;--shiki-dark:#89DDFF;--shiki-dark-font-weight:bold}html pre.shiki code .sf2UM, html code.shiki .sf2UM{--shiki-light:#E53935;--shiki-light-font-weight:bold;--shiki-default:#F07178;--shiki-default-font-weight:bold;--shiki-dark:#F07178;--shiki-dark-font-weight:bold}html pre.shiki code .sLSIA, html code.shiki .sLSIA{--shiki-light:#E53935;--shiki-light-font-style:italic;--shiki-default:#F07178;--shiki-default-font-style:italic;--shiki-dark:#F07178;--shiki-dark-font-style:italic}",{"id":109,"title":2474,"titles":2475,"content":2476,"level":270},"Server Hosting",[],"Node preset is the default preset for Nuxt and Nuxt Content. It is used to build and run Nuxt applications on Node.js.",{"id":2478,"title":2479,"titles":2480,"content":2481,"level":303},"/docs/deploy/server#what-is-nodejs-preset","What is Node.js preset?",[2474],"Node preset is the default preset for Nuxt, when building your project, Nuxt will output a Node.js server that you can run with node .output/server/index.mjs.",{"id":2483,"title":2484,"titles":2485,"content":2486,"level":303},"/docs/deploy/server#building-with-nodejs-preset","Building with Node.js preset",[2474],"Build project with Nuxt build command: nuxi build When running nuxi build with the Node server preset, the result will be an entry point that launches a ready-to-run Node server. $ node .output/server/index.mjs\nListening on http://localhost:3000 The SQLite database will be loaded on the server side when booting the server as well as in the browser for client-side navigation or actions. html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":113,"title":2488,"titles":2489,"content":2490,"level":270},"Serverless Hosting",[],"How to deploy Nuxt Content on various serverless platforms.",{"id":2492,"title":2493,"titles":2494,"content":2495,"level":303},"/docs/deploy/serverless#what-is-serverless-hosting","What is Serverless Hosting?",[2488],"Serverless hosting lets you run code and applications without managing servers directly - you just upload your code and the cloud provider automatically handles all the infrastructure, scaling, and maintenance while charging you only for the actual compute resources you use. In serverless environments, each user request triggers a fresh instance of your Nuxt server, meaning it starts from scratch every time. This \"stateless\" nature means you can't store data in server memory or use file-based databases like SQLite. That's why we need to use external database services (like D1, Turso, or PostgreSQL) that persist data independently of your server instances.",{"id":2497,"title":2498,"titles":2499,"content":2500,"level":303},"/docs/deploy/serverless#deploy-with-serverless","Deploy with Serverless",[2488],"The module have built-in support for couple of famous serverless platforms. You can deploy your project to them with ease. Checkout the guides for each platform: NuxtHubCloudflare PagesVercel If you like to deploy to other platforms, you can follow below steps to deploy your project.",{"id":2502,"title":2503,"titles":2504,"content":2505,"level":371},"/docs/deploy/serverless#_1-select-a-database-service","1. Select a database service",[2488,2498],"Before deploying your project, you need to select a database service: // 1. Create a PostgreSQL database\n// 2. And add the `POSTGRES_URL` to the env variables\nexport default defineNuxtConfig({\n  content: {\n    database: {\n      type: 'postgres',\n      url: process.env.POSTGRES_URL\n    }\n  }\n})\n// 1. Create a D1 database in your CF account\n// 2. Link it to your project with the same binding name\nexport default defineNuxtConfig({\n  content: {\n    database: {\n      type: 'd1',\n      binding: '\u003CYOUR_BINDING_NAME>'\n    }\n  }\n})\n// 1. Create a LibSQL database on Turso.tech\n// 2. And add the `TURSO_DATABASE_URL` and `TURSO_AUTH_TOKEN` env variables\nexport default defineNuxtConfig({\n  modules: ['@nuxt/content'],\n  content: {\n    database: {\n      type: 'libsql',\n      url: process.env.TURSO_DATABASE_URL,\n      authToken: process.env.TURSO_AUTH_TOKEN,\n    }\n  }\n})\n// Install the NuxtHub module (see hub.nuxt.com)\nexport default defineNuxtConfig({\n  modules: ['@nuxt/content', '@nuxthub/core'],\n  content: {\n    database: {\n      type: 'd1',\n      binding: 'DB'\n    }\n  },\n  hub: {\n    database: true\n  }\n})",{"id":2507,"title":2508,"titles":2509,"content":2510,"level":371},"/docs/deploy/serverless#_2-deploy-your-project","2. Deploy your project",[2488,2498],"Nuxt Content uses Nuxt deployment presets to adjust the build process for different hosting platforms. Various serverless platform are supported with zero configuration: CloudflareNuxtHubVercelNetlify All you need to do is to set the build command to: nuxi build The generated output will be compatible with the selected platform. The linked database will be loaded on the server side when booting the server. In the browser, a WASM SQLite database will be loaded for client-side navigation and actions. If you wish to deploy to AWS Lambda, you need to make sure your sqlite file is in /tmp since this is the only writeable folderexport default defineNuxtConfig({\n  modules: ['@nuxt/content'],\n  content: {\n    database: {\n      type: 'sqlite',\n      filename: '/tmp/contents.sqlite'\n    }\n  }\n})",{"id":2512,"title":2513,"titles":2514,"content":2515,"level":371},"/docs/deploy/serverless#_3-optimize-with-pre-rendering","3. Optimize with pre-rendering",[2488,2498],"As each request trigger a fresh instance of your Nuxt server, the performance of your serverless application will be impacted if you don't pre-render some pages. To optimize your serverless application, you can pre-render your pages using the routeRules option: export default defineNuxtConfig({\n  routeRules: {\n    '/': { prerender: true }\n  }\n}) We recommend to checkout NuxtHub's Pre-rendering guide to learn more about the different strategies to optimize your serverless application, it applies to all serverless platforms. html pre.shiki code .syuKq, html code.shiki .syuKq{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sPKOg, html code.shiki .sPKOg{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"id":117,"title":116,"titles":2517,"content":2518,"level":270},[],"Deploy your Content app to NuxtHub Quick SetupInstall the @nuxthub/core module nuxi module add hubUse npx nuxthub deploy to deploy your content to NuxtHub Nuxt Content module has a built-in integration with NuxtHub to deploy your content. To enable NuxtHub integration, you need to install the @nuxthub/core module and register it in your nuxt.config.ts. More efficiently, you can use nuxi module command to do both at once. npx nuxi module add hub That's it 🎉 Now you can use the npx nuxthub deploy command to deploy your content to NuxtHub. npx nuxthub deploy Nuxt Content module automatically enables NuxtHub database. And update database configuration to use Cloudflare D1 with DB binding name. (This is default configuration for NuxtHub database.)You can override the database configuration by providing your own database configuration in nuxt.config.ts. Checkout the NuxtHub documentation for more information. html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":121,"title":120,"titles":2520,"content":2521,"level":270},[],"Deploy your Content app to Cloudflare Pages Quick SetupUse nuxi build --preset=cloudflare_pages to build your appCreate D1 database and connect to your project in Cloudflare Dashboard under DB binding nameDeploy/Redeploy your app Nuxt Content module has a built-in integration with Cloudflare Pages to deploy your content. Module will automatically detects the build target and prepare the necessary configuration for Cloudflare Pages. Content module currently only support cloudflare-pages presets. You can either use --preset=cloudflare_pages option on nuxi build command or use nuxt.config.ts to configure the preset. export default defineNuxtConfig({\n  nitro: {\n    preset: 'cloudflare_pages',\n  },\n}); The module requires a D1 database to be connected to the app in order to work. By default it will use the DB binding name. You can override the database configuration by providing your own database configuration in nuxt.config.ts. After creating a new Cloudflare Pages project, you need to create a new D1 database and connect it to the project. Make sure to use the same binding name as the module is using. (default is DB) That's it 🎉 Checkout: Nuxt Deploy documentationCloudflare D1 documentationCloudflare Pages documentation html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":125,"title":124,"titles":2523,"content":2524,"level":270},[],"Deploy your Content app to Vercel Quick SetupExeceute npx vercel deploy command or go to Vercel dashboard and create a new project using git repository. Nuxt Content projects can be deployed to Vercel with zero configuration. The module will automatically detects Vercel environment and prepare the necessary configuration for Vercel. All you need to do is to execute npx vercel deploy command or go to Vercel dashboard and create a new project using git repository. That's it 🎉 By default module will use SQlite database in Vercel located at /tmp directory. You can override the database configuration by providing your own database configuration.There are a couple of database providers that are supported by Vercel. You can use any of them by providing the correct connection string in nuxt.config.ts. Checkout: Nuxt Deploy documentationVercel documentation",{"id":129,"title":128,"titles":2526,"content":2527,"level":270},[],"Deploy your Content app with Docker Docker is a popular containerization platform that allows you to package your application with all its dependencies into a single container. This makes it easy to deploy your Content app on any platform that supports Docker.",{"id":2529,"title":2530,"titles":2531,"content":2532,"level":303},"/docs/deploy/docker#with-nodejs-image","With Node.js image",[128],"Using Docker's Node.js image, you can deploy your Content app. All you need is to create a Dockerfile and build the image. Here is an example Dockerfile: # Build Stage 1\n\nFROM node:22-alpine AS build\nWORKDIR /app\n\nRUN corepack enable\n\n# Copy package.json and your lockfile, here we add pnpm-lock.yaml for illustration\nCOPY package.json pnpm-lock.yaml .npmrc ./\n\n# Install dependencies\nRUN pnpm i\n\n# Copy the entire project\nCOPY . ./\n\n# Build the project\nRUN pnpm run build\n\n# Build Stage 2\n\nFROM node:22-alpine\nWORKDIR /app\n\n# Only `.output` folder is needed from the build stage\nCOPY --from=build /app/.output/ ./\n\n# Change the port and host\nENV PORT 80\nENV HOST 0.0.0.0\n\nEXPOSE 80\n\nCMD [\"node\", \"/app/server/index.mjs\"]",{"id":2534,"title":2535,"titles":2536,"content":2537,"level":303},"/docs/deploy/docker#with-bun-image","With Bun image",[128],"If you like to use Bun, you can use the official Bun image. Here is an example Dockerfile: # use the official Bun image\n# see all versions at https://hub.docker.com/r/oven/bun/tags\nFROM oven/bun:1 AS build\nWORKDIR /app\n\nCOPY package.json bun.lockb ./\n\n# use ignore-scripts to avoid builting node modules like better-sqlite3\nRUN bun install --frozen-lockfile --ignore-scripts\n\n# Copy the entire project\nCOPY . .\n\nRUN bun --bun run build\n\n# copy production dependencies and source code into final image\nFROM oven/bun:1 AS production\nWORKDIR /app\n\n# Only `.output` folder is needed from the build stage\nCOPY --from=build /app/.output /app\n\n# run the app\nEXPOSE 3000/tcp\nENTRYPOINT [ \"bun\", \"--bun\", \"run\", \"/app/server/index.mjs\" ] html pre.shiki code .syuKq, html code.shiki .syuKq{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .smPcV, html code.shiki .smPcV{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":133,"title":2539,"titles":2540,"content":1655,"level":270},"Static Hosting",[],{"id":2542,"title":2543,"titles":2544,"content":2545,"level":303},"/docs/deploy/static#what-is-static-hosting","What is Static Hosting?",[2539],"Static hosting is a type of hosting where your website is built and served as static files (HTML, CSS, JS) that can be served by any static file server. Nuxt Content can be deployed to static hosting using Nuxt prerendering.",{"id":2547,"title":2548,"titles":2549,"content":2550,"level":303},"/docs/deploy/static#building-with-ssg","Building with SSG",[2539],"To build your app with static site generation, run the following command: npx nuxi generate This command will create a dist/ directory with your static site. You can upload it to any static hosting service. Nuxt will automatically pre-render all pages using an internal crawler, you can customize it's behavior with the nitro.prerender options. Learn more about pre-rendering in Nuxt.",{"id":2552,"title":2553,"titles":2554,"content":2555,"level":303},"/docs/deploy/static#what-about-the-database","What about the Database?",[2539],"Nuxt Content will load the database in the browser using WASM SQLite, this way, the content queries happening on client-side navigation or actions will run in the browser. html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":143,"title":142,"titles":2557,"content":2558,"level":270},[],"Implement full-text search in your website using Nuxt Content Content module exposes a handy utility queryCollectionSearchSections to break down content files into searchable sections. This is useful for implementing full-text search in your website. You can use the result of this utility in combination with Nuxt UI Content Search or other search libraries like Fuse.js, minisearch, etc.",{"id":2560,"title":235,"titles":2561,"content":2562,"level":303},"/docs/advanced/fulltext-search#nuxt-ui-pro",[142],"Nuxt UI Pro provides a ready to use component for full-text search. You can use it by passing the result of queryCollectionSearchSections to the files prop of the component. Read more about Nuxt UI Content Search. \u003Cscript setup lang=\"ts\">\nconst { data: navigation } = await useAsyncData('navigation', () => queryCollectionNavigation('docs'))\nconst { data: files } = await useAsyncData('search', () => queryCollectionSearchSections('docs'))\n\nconst searchTerm = ref('')\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CUContentSearch\n    v-model:search-term=\"searchTerm\"\n    :files=\"files\"\n    :navigation=\"navigation\"\n    :fuse=\"{ resultLimit: 42 }\"\n  />\n\u003C/template>",{"id":2564,"title":565,"titles":2565,"content":2566,"level":303},"/docs/advanced/fulltext-search#minisearch-example",[142],"Read more about minisearch. \u003Cscript setup lang=\"ts\">\nimport MiniSearch from 'minisearch'\n\nconst query = ref('')\nconst { data } = await useAsyncData('search', () => queryCollectionSearchSections('docs'))\n\nconst miniSearch = new MiniSearch({\n  fields: ['title', 'content'],\n  storeFields: ['title', 'content'],\n  searchOptions: {\n    prefix: true,\n    fuzzy: 0.2,\n  },\n})\n\n// Add data to the MiniSearch instance\nminiSearch.addAll(toValue(data.value))\nconst result = computed(() => miniSearch.search(toValue(query)))\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CUContainer class=\"p-4\">\n    \u003CUCard>\n      \u003CUInput v-model=\"query\" placeholder=\"Search...\" />\n      \u003Cul>\n        \u003Cli v-for=\"link of result\" :key=\"link.id\" class=\"mt-2\">\n          \u003CNuxtLink :to=\"link.id\">{{ link.title }}\u003C/NuxtLink>\n          \u003Cp class=\"text-gray-500 text-xs\">{{ link.content }}\u003C/p>\n        \u003C/li>\n      \u003C/ul>\n    \u003C/UCard>\n  \u003C/UContainer>\n\u003C/template>",{"id":2568,"title":1147,"titles":2569,"content":2570,"level":303},"/docs/advanced/fulltext-search#fusejs-example",[142],"Read more about Fuse.js. \u003Cscript setup lang=\"ts\">\nimport Fuse from 'fuse.js'\n\nconst query = ref('')\nconst { data } = await useAsyncData('search-data', () => queryCollectionSearchSections('docs'))\n\nconst fuse = new Fuse(data.value, {\n  keys: ['title', 'description']\n})\n\nconst result = computed(() => fuse.search(toValue(query)).slice(0, 10))\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CUContainer class=\"p-4\">\n    \u003CUCard>\n      \u003CUInput v-model=\"query\" placeholder=\"Search...\" class=\"w-full\" />\n      \u003Cul>\n        \u003Cli v-for=\"link of result\" :key=\"link.item.id\" class=\"mt-2\">\n          \u003CUButton variant=\"ghost\" class=\"w-full\" :to=\"link.item.id\">\n            {{ link.item.title }}\n            \u003Cspan class=\"text-gray-500 text-xs\">\n              {{ link.item.content?.slice(0, 100) }}...\n            \u003C/span>\n          \u003C/UButton>\n        \u003C/li>\n      \u003C/ul>\n    \u003C/UCard>\n  \u003C/UContainer>\n\u003C/template> html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sPKOg, html code.shiki .sPKOg{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .smPcV, html code.shiki .smPcV{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .syuKq, html code.shiki .syuKq{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"id":147,"title":146,"titles":2572,"content":2573,"level":270},[],"Access to contents raw data in appliction There were lots of requests in Content version 2 about accessing contents raw data in production. In Content version 3 it is possible to ship contents raw data to production. In order to ship raw contents to production you need to define rawbody field in your collection's schema. That's it. Nuxt Content will detect this magical field in your schema and fill it with the raw content. import { defineCollection, defineContentConfig, z } from '@nuxt/content'\n\nexport default defineContentConfig({\n  collections: {\n    docs: defineCollection({\n      source: '**',\n      type: 'page',\n      schema: z.object({\n        rawbody: z.string()\n      })\n    })\n  }\n}) And you can use queryCollection() to fetch the raw content. \u003Cscript setup lang=\"ts\">\nconst route = useRoute()\nconst { data } = useAsyncData('page-' + route.path, () => queryCollection('docs').path(route.path).first())\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cpre>{{ data.rawbody }}\u003C/pre>\n\u003C/template> In case you don't want to ship raw content of a specific file you can add rawbody: '' to frontmatter of that file. The auto filled value of rawbody is acting like default value and when you define rawbody in the frontmatter it will overwritten. ---\ntitle: My page\nrawbody: ''\n--- It is important to fill frontmatter fields with a same type of data that is defined in collection schema. In this case rawbody is a string, and you should consider passing empty string. Do not use boolean or other type of values. html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}",{"id":151,"title":2575,"titles":2576,"content":2577,"level":270},"Database",[],"How Nuxt Content stores and retrieves content In Content v3, we have introduced a robust storage layer based on SQLite, which offers a powerful and efficient method for managing content. This marks a significant enhancement over the previous file-based storage system, which was constrained by performance and scalability limitations. In Content v2, the system read and parsed content during the Nitro runtime, creating a cache file for each content file to store the parsed data. This method introduced considerable overhead to the website's runtime.The I/O time in production was substantial, as the module had to load all cache files to search through the content.Additionally, the lack of optimization and compression for the content resulted in a large bundle size, particularly problematic in edge environments. Content management in Content v3 involves three key steps, which are designed to streamline the process and enhance performance.",{"id":2579,"title":2580,"titles":2581,"content":2582,"level":303},"/docs/advanced/database#generating-database-dump","Generating Database Dump",[2575],"For each collection in your project, the module reads the content from the defined source and parses it into an Abstract Syntax Tree (AST). It creates a specific table for each collection based on its schema. The parsed content is then inserted into the corresponding table, ensuring that the data structure aligns with the defined schema for optimal querying. Everything is then saved in a dump file.",{"id":2584,"title":2585,"titles":2586,"content":2587,"level":303},"/docs/advanced/database#restoring-dump-on-cold-start","Restoring Dump on Cold Start",[2575],"During runtime, when the application executes the first query to retrieve content, the module reads the generated dump from the previous step and restores it into the target database. This process is fast and optimized for each deployment mode and platform. The module employs a special integrity check mechanism to ensure that the database is updated with the latest content. This same integrity check also prevents duplicate imports, maintaining the integrity and accuracy of the data stored.",{"id":2589,"title":2590,"titles":2591,"content":2592,"level":303},"/docs/advanced/database#wasm-sqlite-in-browser","WASM SQLite in Browser",[2575],"For client-side navigation, the module utilizes a similar approach. When the application executes the first query for content, it downloads the generated dump from the server and initializes a local SQLite database within the browser. From that point onward, all queries are executed locally without needing to call the server, significantly improving the responsiveness of the application and providing a seamless user experience. This architecture not only enhances performance but also allows for offline capabilities, enabling users to access content even without an active internet connection. The combination of server-side and client-side processing ensures that Nuxt Content v3 is both powerful and flexible, catering to a wide range of use cases and environments.",{"id":155,"title":2594,"titles":2595,"content":2596,"level":270},"Tools",[],"Debugging tools Nuxt Content uses an SQLite database (contents.sqlite) to store and query content efficiently. If you're running into missing content, slow queries, or database issues, debugging your SQLite database can help! A simple way to inspect it? Use the SQLite VS Code extension!",{"id":2598,"title":2599,"titles":2600,"content":2601,"level":303},"/docs/advanced/tools#install-sqlite-vs-code-extension","Install SQLite VS Code Extension",[2594],"Open Visual Studio Code.Go to the Extensions panel (Ctrl+Shift+X / Cmd+Shift+X on Mac).Search for \"SQLite\" (by alexcvzz) and install it.Open your Nuxt Content database (.data/content/contents.sqlite). If you don't see contents.sqlite, start your Nuxt app first:npx nuxi dev",{"id":2603,"title":2604,"titles":2605,"content":2606,"level":303},"/docs/advanced/tools#locate-your-sqlite-database","Locate Your SQLite Database",[2594],"Nuxt Content stores its database here: .data/content/contents.sqlite This file is automatically generated when you start your Nuxt app. No need to create it manually!",{"id":2608,"title":2609,"titles":2610,"content":2611,"level":303},"/docs/advanced/tools#open-explore-the-database","Open & Explore the Database",[2594],"Right-click on contents.sqlite in VS Code.Select \"Open Database\".Expand the Database Explorer panel to view tables & data.",{"id":2613,"title":2614,"titles":2615,"content":263,"level":303},"/docs/advanced/tools#fixing-common-issues","Fixing Common Issues",[2594],{"id":2617,"title":2618,"titles":2619,"content":2620,"level":371},"/docs/advanced/tools#content-not-showing","Content Not Showing?",[2594,2614],"Check if the database exists (.data/content/contents.sqlite).Run a cleanup & restart Nuxt:\nnpx nuxi cleanup && npx nuxi dev\nCheck if content is inside the database (run an SQL query).",{"id":2622,"title":2623,"titles":2624,"content":2625,"level":371},"/docs/advanced/tools#manually-reset-the-database","Manually Reset the Database",[2594,2614],"If things seem really broken, try resetting it: Delete the database file:\nrm -rf .data/content/contents.sqlite\nRun cleanup to remove old caches:\nnpx nuxi cleanup\nRestart Nuxt to generate a fresh database:\nnpx nuxi dev Cleaning up will remove cached data. Don't worry—it regenerates automatically!",{"id":2627,"title":2628,"titles":2629,"content":2630,"level":303},"/docs/advanced/tools#more-debugging-tools","More Debugging Tools",[2594],"If VS Code isn’t enough, check out: 🖥️ DB Browser for SQLite – A visual tool for inspecting & modifying the database.🛠️ SQLite Command Line – Use sqlite3 contents.sqlite to run SQL queries from your terminal. html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}",{"id":159,"title":158,"titles":2632,"content":2633,"level":270},[],"Modify your content using Nuxt build time hooks",{"id":2635,"title":2636,"titles":2637,"content":2638,"level":303},"/docs/advanced/hooks#contentfilebeforeparse","content:file:beforeParse",[158],"This hook is called before the content is parsed. It can be used to modify the raw content from a file before it is transformed\nor modify the transform options. export default defineNuxtConfig({\n  hooks: {\n    'content:file:beforeParse'(ctx) {\n      // ...\n    }\n  }\n})",{"id":2640,"title":2641,"titles":2642,"content":2643,"level":303},"/docs/advanced/hooks#contentfileafterparse","content:file:afterParse",[158],"This hook is called after the content is parsed and before it is saved to the database. export default defineNuxtConfig({\n  hooks: {\n    'content:file:afterParse'(ctx) {\n      // ...\n    }\n  }\n}) html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sK9QF, html code.shiki .sK9QF{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .syuKq, html code.shiki .syuKq{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"id":163,"title":162,"titles":2645,"content":2646,"level":270},[],"Define a custom source to retrive data. By default, Nuxt Content provides some built-in sources like local files source and remote Github source. However this is not enough for some cases, for example, you want to fetch data from a remote API. In this case, you can define a custom source to fetch data and use it in your collections. Using defineCollectionSource, you can define a custom source. import { defineCollectionSource } from '@nuxt/content'\n\nconst hackernewsSource = defineCollectionSource({\n  getKeys: () => {\n    return fetch('https://hacker-news.firebaseio.com/v0/topstories.json')\n      .then(res => res.json())\n      .then(data => data.map((key: string) => `${key}.json`))\n  },\n  getItem: (key: string) => {\n    const id = key.split('.')[0]\n    return fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`)\n      .then(res => res.json())\n  },\n}) Then you can use this source in your collections. import { defineContentConfig, defineCollectionSource, defineCollection, z } from '@nuxt/content'\n\nconst hackernewsSource = defineCollectionSource({\n  getKeys: () => {\n    return fetch('https://hacker-news.firebaseio.com/v0/topstories.json')\n      .then(res => res.json())\n      .then(data => data.map((key: string) => `${key}.json`))\n  },\n  getItem: (key: string) => {\n    const id = key.split('.')[0]\n    return fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`)\n      .then(res => res.json())\n  },\n})\n\nconst hackernews = defineCollection({\n  type: 'data',\n  source: hackernewsSource,\n  schema: z.object({\n    title: z.string(),\n    date: z.date(),\n    type: z.string(),\n    score: z.number(),\n    url: z.string(),\n    by: z.string(),\n  }),\n})\n\nexport default defineContentConfig({\n  collections: {\n    hackernews,\n  },\n}) html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sK9QF, html code.shiki .sK9QF{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .smPcV, html code.shiki .smPcV{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":173,"title":2648,"titles":2649,"content":2650,"level":270},"Setup Nuxt Studio",[],"Studio is the intuitive CMS interface to edit Nuxt Content websites. Edit your Markdown, YAML and JSON files and publish your changes to GitHub. Studio is an intuitive CMS interface to edit your Nuxt Content websites. It take advantage of the Preview API included in Nuxt Content to propose the best editing experience for your content files. Editors can benefit from a user-friendly interface to edit their Markdown, YAML or JSON files. Developers can customize the edition experience and provide tools to the editor who can focus on content without requiring any technical expertise.",{"id":2652,"title":2653,"titles":2654,"content":2655,"level":303},"/docs/studio/setup#authentication","Authentication",[2648],"The Studio admin is located on nuxt.studio. From there you can either login with GitHub or with Google. Both methods give you the same edition rights but since Studio is synchronized with GitHub, the repository import must be handled by a GitHub user. Google authentication is adapted for non technical users. Google users have to join a team with existing projects to edit them.",{"id":2657,"title":2658,"titles":2659,"content":2660,"level":303},"/docs/studio/setup#connect-your-nuxt-content-repository","Connect your Nuxt Content Repository",[2648],"Once you are logged in the admin, you have the possibility to import your Nuxt Content repository from the interface. Two options are available, you can either import an existing repository or use one of our templates. The only requirement is to host your repository on GitHub. From the interface, connect to our GitHub app, you'll be then able to link a GitHub repository to your Studio project. Once the project is created, you can start editing your files with the Studio editors and publish your changes.",{"id":2662,"title":2663,"titles":2664,"content":2665,"level":303},"/docs/studio/setup#enable-the-full-editing-experience","Enable the Full Editing Experience",[2648],"To unlock the complete range of features in Studio, make sure your project URL is properly configured in the deployment section. This will enable all Studio features including: Live preview of your website: instantly see changes reflected on your site as you work.Dynamic form generation: Automatically generate forms to edit your files based on your Nuxt Content collections.Enhanced markdown editors: enjoy an improved editing experience, including the ability to list and integrate Vue components that you’ve exposed.Automatic app configuration: generate application configurations based on the schema you’ve defined. We are proposing a GitHub Pages deployment. By using it, we will handle all the requirements for you. However, if you want to use the deployment platform of your choice, please follow the simple guideline below. To be able to set your URL in Studio, you just need to set the Preview API in the content configuration of your nuxt.config.ts file. export default defineNuxtConfig({\n  content: {\n    preview: {\n      api: 'https://api.nuxt.studio'\n    }\n  }\n}) Once deployed, you can ensure the Preview API has been activated by navigating to the /__preview.json page on your site. This metadata page is automatically generated by the Content module and must be accessible to connect your URL in the self-hosted section of Studio.",{"id":2667,"title":2668,"titles":2669,"content":2670,"level":371},"/docs/studio/setup#troubleshooting","Troubleshooting",[2648,2663],"The __preview.json file is generated but you encounter a Forbidden error: invalid property check when setting your URL in the self-hosted section, follow these steps: Ensure the gitInfo field is set and accurate in the __preview.json file\"gitInfo\": {\n  \"name\": \"content\",\n  \"owner\": \"nuxt\",\n  \"url\": \"https://github.com/nuxt/content\"\n},\nThis information should be populated automatically in most cases. We support most popular providers (NuxtHub, Vercel, Netlify, etc.), but if you're using a non supported provider or a custom one, it may not be fetched correctly.Override gitInfo in your nuxt.config.tsexport default defineNuxtConfig({\n  content: {\n    preview: {\n      api: 'https://api.nuxt.studio',\n      gitInfo: {\n        name: 'Your repository name',\n        owner: 'Your repository owner/organization',\n        url: 'Your GitHub repository URL'\n      }\n    }\n  }\n})\nEnsure these fields are correctly set in __preview.jsonThe Forbidden error should be resolved and you should be able to set your URL on Nuxt Studio. If not, please contact us on the Discord server. html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}",{"id":177,"title":2672,"titles":2673,"content":2674,"level":270},"Real time synchronization between Studio and GitHub",[],"Nuxt Studio is natively synced with GitHub. Install the Nuxt Studio GitHub app and enable content publication on GitHub directly from Studio. This section explains the syncronization behaviour between Studio and GitHub. This process is handled directly from the platform and does not require any external action. This page purpose is purely informational.",{"id":2676,"title":2677,"titles":2678,"content":2679,"level":303},"/docs/studio/github#overview","Overview",[2672],"Nuxt Studio integrates with the GitHub API, enabling smooth synchronization between Studio and your GitHub repositories. This first-class integration is made possible through the utilization of GitHub Apps.",{"id":2681,"title":12,"titles":2682,"content":2683,"level":303},"/docs/studio/github#installation",[2672],"During Studio project creation, you'll need to install the Nuxt Studio GitHub App in your personal account or in the organizations you manage. Installing a GitHub App requires either organization ownership or admin permissions in a repository. If you lack the necessary permissions, the repository owner will need to approve the request. You can access the installation page from anywhere on the app by clicking on Install with GitHub.",{"id":2685,"title":2686,"titles":2687,"content":2688,"level":371},"/docs/studio/github#permissions","Permissions",[2672,12],"During the installation of our GitHub app, you will be prompted to grant certain permissions: Read access to actions, metadata, members, and planRead and write access to secrets, administration, contents, pages, pull requests and workflows We need read access to actions to send a notification when a workflow run fails on a pull request or on the repository default branch. metadata is mandatory to fetch repository data, members to import your organization members and repository collaborators and plan is used to propose features based on your GitHub account plan. Nuxt Studio acts on your behalf to create repositories, branches, pull requests, and perform commits and merges. We also offer one-click deployment to GitHub Pages with instant preview of workflows and environment variables secrets management. To accomplish this, we need read and write access to administration, contents, pages, pull requests, workflows and secrets.",{"id":2690,"title":2691,"titles":2692,"content":2693,"level":371},"/docs/studio/github#repositories-installations","Repositories Installations",[2672,12],"When installing our GitHub app, you will be prompted to select all repositories or a subset of them. This selection can be changed at any time by going to the GitHub app settings. By clicking on Install, Nuxt Studio will install each repository you have selected, enabling you to perform all the actions listed above.",{"id":2695,"title":2696,"titles":2697,"content":2698,"level":303},"/docs/studio/github#uninstall","Uninstall",[2672],"All the data imported from GitHub is directly associated with your GitHub app installation. If you uninstall the GitHub app, all the associated data will be deleted. If you delete your GitHub repository, the associated Nuxt Studio project will be automatically removed. However, if this project was subscribed to a Team plan, the subscription will not be canceled automatically. You will need to manually end the subscription via Lemon Squeezy or contact us for assistance.",{"id":181,"title":2700,"titles":2701,"content":2702,"level":270},"Edit your content",[],"Discover and select your favorite way to manage your content between the visual or the code editor. Nuxt Studio offers a versatile workspace for both developers and content writers, giving them the freedom to choose between our differents editors: Notion-like editor for Markdown filesForm editor for YAML and JSON filesCode editor for any kind of files (for technical users only) You can choose your favorite editor from the settings page of your project. Each editor serves its own purpose. Some users are used to code edition, while others prefer a non-technical, visual approach. At the end, code syntax is the final output for both editors.",{"id":2704,"title":2705,"titles":2706,"content":2707,"level":303},"/docs/studio/content#notion-like-editor-markdown-files","Notion-like editor (Markdown files)",[2700],"This editor is heavily inspired by Notion, well known for its intuitive design and flexibility. Much like a standard text editor, this editor is designed to be familiar and easy to use. However, it stands out with its additional features that improve the writing experience. You want to know how we've built this editor and how it works under the hood? Check this blog post.",{"id":2709,"title":2022,"titles":2710,"content":2711,"level":371},"/docs/studio/content#frontmatter",[2700,2705],"Frontmatter is a convention of Markdown-based CMS to provide meta-data to pages, like description or title or any other data you would like to store as key: value pair. Based on the user collection and schema provided, a form is generated to edit this metadata from the editor.",{"id":2713,"title":2714,"titles":2715,"content":2716,"level":371},"/docs/studio/content#toolbar","Toolbar",[2700,2705],"Highlight your text to reveal the toolbar, giving you access to all the standard text editing features (title formatting, Bold, Italic, Strike-through, code, link, class, bullet list, numerated list...).",{"id":2718,"title":184,"titles":2719,"content":2720,"level":371},"/docs/studio/content#medias",[2700,2705],"Users can simply drag and drop images directly into the editor. An upload modal will open to let you choose the destination folder. By typing / and searching for Image or Video, they can quickly insert a media. A modal will open to let them choose the media they want to insert from the media gallery (aka thepublic folder of the Nuxt application). From the media modal, you can set the alt attribute for SEO and accessibility purpose.",{"id":2722,"title":2042,"titles":2723,"content":2724,"level":371},"/docs/studio/content#vue-components",[2700,2705],"One of this editor standout features is its ability to integrate and customize any complex Vue component directly within the editor.",{"id":2726,"title":2727,"titles":2728,"content":2729,"level":421},"/docs/studio/content#create-and-integrate-your-own-component","Create and integrate your own component",[2700,2705,2042],"A developer can create any kind of visually complex components and editors will be able to use them and focus on the content. An editor can also play with the component properties, styles, and behaviour to fit its specific requirements as long as the developer made it customisable. Create your componentYou can create Vue components and integrate them into Markdown. They just need to be located in the /components/content folder to be available.\u003Ctemplate>\n  \u003Cdiv class=\"flex items-start gap-3\">\n    \u003Cdiv class=\"flex items-center justify-center border rounded-lg p-1.5\">\n      \u003CUIcon :name=\"icon\" />\n    \u003C/div>\n    \u003Cdiv class=\"flex flex-col\">\n      \u003Ch3 class=\"font-semibold\">\n        \u003CContentSlot name=\"title\" />\n      \u003C/h3>\n      \u003Cspan>\n        \u003CContentSlot name=\"description\" />\n      \u003C/span>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\ndefineProps({\n  icon: {\n    type: String,\n    default: 'i-ph-cursor-click',\n  },\n})\n\u003C/script>\nIntegrate these components easily within any Markdown file using MDC syntax::home-feature\n  ---\n  icon: i-mdi-vuejs\n  ---\n  #title\n  Embedded Vue components\n  #description\n  Edit slots and props inside the Notion-like editor.\n::\nEdit them with our Studio editorsThe visual editor simplifies the component edition, allowing you to integrate and edit them directly in the visual editor. Non technical users can play with slots and props without any technical knowledge.All components in the /components/content folder are available in the editor. Studio users can type / anywhere while editing to access the list of available components.Take a look at this section to validate your Vue component integration in the editor in local development.",{"id":2731,"title":2732,"titles":2733,"content":2734,"level":421},"/docs/studio/content#integrate-built-in-components-from-external-libraries","Integrate built-in components from external libraries",[2700,2705,2042],"By default, you can integrate any component inside a Markdown file and it should work and be editable from Studio but external components won't be displayed in the components list in Studio and can't be integrated manually by a Studio editor. To list this component inside Studio and fetch all its metadata, you need to set it as global in your Nuxt config file. Here is an example to integrate Button and Icon components from the Nuxt UI library: export default defineNuxtConfig({\n  hooks: {\n    'components:extend': (components) => {\n      const globals = components.filter(c => ['UButton', 'UIcon'].includes(c.pascalName))\n\n      globals.forEach(c => c.global = true)\n    }\n  },\n})",{"id":2736,"title":2737,"titles":2738,"content":2739,"level":303},"/docs/studio/content#form-editor-yaml-and-json-files","Form editor (YAML and JSON files)",[2700],"This editor removes the need for users to interact directly with complex file syntax such as YAML or JSON. Based on the user collection and schema provided, a form is generated for both YAML and JSON files. Arrays are not yet handled but should be generated soon thanks to collections and user-defined schemas.",{"id":2741,"title":2742,"titles":2743,"content":2744,"level":303},"/docs/studio/content#code-editor","Code editor",[2700],"Even though the two previous editors are dedicated to a specific file extension (md or yaml/json). The code editor can be used with any kind of file. It provides full control over your content, allowing you to write raw content directly: MDC syntax for Markdown filesJSON or YAML syntax When your file is saved with the code editor, the content is stored exactly as you've written it, preserving all specific syntax and formatting. This editor is ideal for users comfortable with code syntax (Markdown, YAML or JSON) who want precise control over structure of their content. html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s50WR, html code.shiki .s50WR{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sK9QF, html code.shiki .sK9QF{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sPKOg, html code.shiki .sPKOg{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"id":185,"title":2746,"titles":2747,"content":2748,"level":270},"Manage and integrate Medias in Nuxt Content Studio CMS",[],"Explore how to browse and manage media files, and integrate them into your projects using Nuxt Content Studio CMS features.",{"id":2750,"title":2751,"titles":2752,"content":2753,"level":303},"/docs/studio/medias#browse-your-medias","Browse your medias",[2746],"All medias located in the /public directory are available in the Media tab of the Studio platform. It's an intuitive interface for non technical users to manage their /public directory. Users can easily browse folders, upload new media at any level, and drag and drop media into other folders, making medias organization straightforward. The interface is designed to be intuitive for non-technical users. It can be viewed as a user friendly IDE.",{"id":2755,"title":2756,"titles":2757,"content":2758,"level":303},"/docs/studio/medias#use-it-in-the-notion-like-editor","Use it in the Notion-like editor",[2746],"Users can simply drag and drop images directly into the editor. An upload modal will open to let you choose the destination folder. By typing / and searching for Image, they can quickly insert a media. A modal will open to let them choose the media they want to insert. From the media modal, you can set the alt attribute for SEO and accessibility purpose.",{"id":189,"title":2760,"titles":2761,"content":2762,"level":270},"Tailor application configuration edition",[],"Discover how to customize application config edition in Studio by providing schema. Ensure a smooth and structured content management experience. When entering the Config tab of the editor, you can browse configurations to customize your website. These configurations represent the settings defined in your app.config.ts file.",{"id":2764,"title":2765,"titles":2766,"content":2767,"level":303},"/docs/studio/config#appconfigts","app.config.ts",[2760],"The app.config.ts file is a configuration file introduced in Nuxt 3. It's a TypeScript file that allows you to configure various aspects of your application settings. Developers can easily turn any website into a configurable experience using this file.",{"id":2769,"title":2770,"titles":2771,"content":2772,"level":303},"/docs/studio/config#customize-edition","Customize edition",[2760],"Ensure you have at least an empty config file in your app.export default defineAppConfig({}) To create a customized editing experience for your app.config.ts in Studio, you need to create a nuxt.schema.ts file in your project. This schema serves as a representation of your app.config.ts.",{"id":2774,"title":2775,"titles":2776,"content":2777,"level":371},"/docs/studio/config#helpers","Helpers",[2760,2770],"Those helpers are provided by the Nuxt Content Preview API. The group method allows you to customize parent objects.The field method allows you to customize inputs (aka leaf). import { field, group } from '@nuxt/content/preview'\n\nexport default defineNuxtSchema({\n  appConfig: {\n    parent: group({\n      title: 'Parent title',\n      description: 'Parent description.',\n      icon: 'i-icon-to-display',\n      fields: {\n        leaf: field({\n          type: 'Type of component used to edit your field',\n          title: 'Field title',\n          description: 'Field Description',\n          icon: 'i-icon-to-display',\n          default: 'default value'\n        })\n      }\n    })\n  }\n}) It is not mandatory to include all your app config keys; only those you wish to showcase on the Studio interface need to be added.",{"id":2779,"title":2780,"titles":2781,"content":2782,"level":421},"/docs/studio/config#input-types","Input Types",[2760,2770,2775],"The type in the field() method's first parameter can accept various values: stringnumberbooleanarrayobjecticonmedia Based on these values, the Studio UI will adapt to display the appropriate input type. For instance, an icon picker is displayed for icon type or the media library is displayed for media type. Text can be displayed as a select instead on a classical input if you provide a required key in the field() method: import { field, group } from '@nuxt/content/preview'\n\nexport default defineNuxtSchema({\n  appConfig: {\n    parent: group({\n      title: 'UI',\n      description: 'UI configuration',\n      icon: 'i-ph-palette-fill',\n      fields: {\n        primary: field({\n          type: 'string',\n          title: 'Primary',\n          description: 'Primary color of your UI.',\n          icon: 'i-ph-palette',\n          default: 'sky',\n          required: ['sky', 'mint', 'rose', 'amber']\n        })\n      }\n    })\n  }\n})",{"id":2784,"title":2785,"titles":2786,"content":2787,"level":371},"/docs/studio/config#edit-on-studio","Edit on Studio",[2760,2770],"Once your schema is deployed. Any user can access the Data section and play with the generated form. Any update in the form will be directly applied to the app.config.ts file. You can review those changes on the review page. export default defineNuxtSchema({\n  ui: group({\n    title: 'UI',\n    description: 'UI Customization.',\n    icon: 'i-mdi-palette-outline',\n    fields: {\n      primary: field({\n        type: 'string',\n        title: 'Primary',\n        description: 'Primary color of your UI.',\n        icon: 'i-mdi-palette-outline',\n        required: ['sky', 'mint', 'rose', 'amber', 'violet', 'emerald', 'fuchsia', '...']\n      }),\n      gray: field({ ... }),\n      icons: group({\n        title: 'Icons',\n        description: 'Manage icons used in UI Pro.',\n        icon: 'i-mdi-application-settings-outline',\n        fields: {\n          search: field({ ...}),\n          dark: field({ ... }),\n          light: field({ ... }),\n          external: field({ ...}),\n          chevron: field({ ... }),\n          hash: field({ ... })\n        }\n      })\n    }\n  })\n}) Take a look at this section to validate your schema in local development. For a practical example, take a look at the schema we've developed for the UI Pro Docs starter. html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"id":193,"title":192,"titles":2789,"content":2790,"level":270},[],"Validate your customization in local development.",{"id":2792,"title":2793,"titles":2794,"content":2795,"level":303},"/docs/studio/debug#purpose","Purpose",[192],"The goal of this section is to explain how to validate your customization in local before publishing on production. It can help if: You want to create a nuxt.schema.ts file and generate the appropriate interface on Studio.You want to integrate custom Vue components and ensure edition is working as expected in the editor.",{"id":2797,"title":2798,"titles":2799,"content":2800,"level":303},"/docs/studio/debug#tutorial","Tutorial",[192],"Import your project on StudioClone your repository on localEnable Nuxt Content preview in developmentexport default defineNuxtConfig({\n  content: {\n    preview: {\n      // force module initialization on dev env\n      dev: true\n    }\n  }\n})\nLaunch your app using your dev command with --tunnel to expose it to the internetnpx nuxt dev --tunnel\nEnsure the metadata file has been generated__preview.json file should accessible from https://your-localtunnel-url/__preview.jsonCopy the tunnel URL and copy it in the self-hosting section of the deployment tab on Studio platform That's it! You should now be able to access Studio UI and confirm that your config interface has been successfully generated and your Vue components are available with their props and slots in the editor. Any modification of your nuxt.config.ts file or any changes in a Vue file require a restart of the Nuxt dev server. Once the server has restarted you can synchronize the Studio interface by calling the Sync meta action from command menu   . A refresh of the Studio app should also apply the update. html pre.shiki code .s8pZq, html code.shiki .s8pZq{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swgpB, html code.shiki .swgpB{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sndM8, html code.shiki .sndM8{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s86vT, html code.shiki .s86vT{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sd2Uz, html code.shiki .sd2Uz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .syuKq, html code.shiki .syuKq{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sPKOg, html code.shiki .sPKOg{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sYGMc, html code.shiki .sYGMc{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sIEYB, html code.shiki .sIEYB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}",1740061578182]