Getting Started

Migration

How to migrate from v2 to v3

Nuxt Content v3 had 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 inevidible.

Don't worry, you don't need to modify your content files, We made sure that Content v3 handles content in the same was as Content v2.

Changes

Here is the list breaking changes in Content v3:

  • queryContent() API is replaced with new queryCollection()
    • New API is backed by SQL
    • New API search contents within the specific collection
  • fetchContentNavigation() API is replaced with new queryCollectionNavigation()
  • Surroundings now has its own separate API queryCollectionItemSurroundings()
  • Document driven mode is fully dropped, meaning:
    • Markdown files will not convert to Nuxt pages automatically, you need to create pages, see how
    • useContent() composable is removed
  • We simplified rendering components.
    • <ContentDoc>, <ContentList>, <ContentNavigation> and <ContentQuery> components are dropped in v3.
  • _dir.yml files are renamed to .navigation.yml
  • Multi source is dropped in favor of multi collection.
  • Document ._path is now renamed to .path
  • searchContent() is dropped in favor of new api queryCollectionSearchSections
  • useContentHelpers() is removed

Implement Document Driven mode in v3

Implementing document driven mode is Content v3 is quite easy. All you need is to create a catch-all page in Nuxt and fetch contents based on route path.

pages/[...slug].vue
<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 droped in favor of new collection based queryCollection. There is two main difference between these two:

  1. queryCollection is builting a query for SQL database.
  2. queryCollection do the search only inside the specific collection. You should know the collection.
Find content with path
// 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()
Find contents with custom filter
// 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 it's 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']
  }
)