Migration
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.
Changes
Vue utils
queryContent()API is replaced with newqueryCollection()
fetchContentNavigation()API is replaced with newqueryCollectionNavigation()- Surroundings now has its own separate API
queryCollectionItemSurroundings() - Document driven mode is dropped:
Markdownfiles 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 newqueryCollectionSearchSectionsAPI- Full text search can easily be done using the
queryCollectionSearchSectionsAPI, check this section to see how
Components
- All content should be rendered using
<ContentRenderer>component.<ContentDoc>,<ContentList>,<ContentNavigation>and<ContentQuery>components are dropped in v3. <ContentSlot>and<MDCSlot>components are not supported in v3. Instead components can simply use Vue's native<slot>component
<ContentSlot> and <MDCSlot> 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 <slot> component. Example: <slot mdc-unwrap="p" />- Components created under the
components/contentdirectory 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.
Types
import type { NavItem } from '@nuxt/content/dist/runtime/types'is remplaced withimport type { ContentNavigationItem } from '@nuxt/content'
General
_dir.ymlfiles are renamed to.navigation.yml- There is no source option in module options, instead you can define multiple sources for your collections in
content.config.ts. - Document
._pathis now renamed to.path, likewise all internal fields with_prefix are removed or renamed. useContentHelpers()is removed
Implement Document Driven mode in v3
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.
<script lang="ts" setup>
const route = useRoute()
const { data: page } = await useAsyncData(route.path, () => {
return queryCollection('content').path(route.path).first()
})
</script>
<template>
<div>
<header><!-- ... --></header>
<ContentRenderer v-if="page" :value="page" />
<footer><!-- ... --></footer>
</div>
</template>
Converting queryContent to queryCollections
As we mentioned above, queryContent is dropped in favor of new collection based queryCollection. There are two main differences between these two:
queryCollectionis building a query for an SQL database.queryCollectiondoes the search only inside the specified collection. You should know the collection's name (key on config).
// Content v2
const v2Query = await queryContent(route.path).findOne()
// Content v3 - don't forget to create `content` collection in `content.config.ts`
const v3Query = await queryCollection('content').path(route.path).first()
// Content v2
const v2Query = await queryContent()
.where({ path: /^\/hello\/.*/ })
.find()
// Content v3 - don't forget to create `content` collection in `content.config.ts`
const v3Query = await queryCollection('content')
.where('path', 'LIKE', '/hello%')
.first()
Convert queryContent().findSurround()
Surround now has its own separate API.
const targetPath = '/docs'
// Content v2
const v2Surround = await queryContent(targetPath)
.only(['title', 'description', 'navigation'])
.findSurround(withoutTrailingSlash(route.path))
// Content v3 - don't forget to create `content` collection in `content.config.ts`
const v3Surround = await queryCollectionItemSurroundings(
'content',
targetPath,
{
fields: ['title', 'description', 'navigation']
}
)
Consolidate ProsePre, ProseCode, and ProseCodeInline components
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
`asProseCodeinstead ofProseCodeInline. - MDC will now map and parse block code starting with three backticks
```asProsePrecomponent.
Suggested Changes:
- Your current
ProseCodelogic should be moved toProsePre - Rename your
ProseCodeInlinecomponents toProseCode