Black Friday Week: 20% off on all Nuxt UI Pro products from Nov 25 to Dec 2!

Nuxt Content

Learn how @nuxt/content module integrates with Nuxt UI Pro.

When building a landing page, a documentation, a blog or even a changelog you will need to manage content. You can do it manually by creating a new page for each content, fetch it from a CMS, store in your own database, etc. or use the @nuxt/content module to manage your content with Git.

Take a look at Nuxt Studio, the Pro version of @nuxt/content which is fully compatible with @nuxt/ui-pro.

Installation

To get started, you can follow the official guide or in summary:

pnpm i @nuxt/content

Then add the module to your nuxt.config.ts:

nuxt.config.ts
export default defineNuxtConfig({
  extends: ['@nuxt/ui-pro'],
  modules: [
    '@nuxt/content',
    '@nuxt/ui'
  ]
})
You need to register @nuxt/content before @nuxt/ui otherwise Tailwind CSS classes won't be parsed in your .md and .yml files.

Now that @nuxt/content module is installed, the layer will automatically configure the syntax highlight theme with material-theme and preload some languages so you don't have to.

Components

You might be using @nuxt/content to build a documentation. To help you with that, we've built some components that you can use in your pages:

  • a full-text search command palette out of the box with the ContentSearch component. No need to setup Algolia DocSearch anymore.
  • a sticky Table of Contents with the ContentToc component
  • a prev / next navigation with the ContentSurround component

Typography

To make the most out of @nuxt/content, we use the @tailwindcss/typography plugin to style your content. The defaults of the plugin have been overriden to use the primary and gray colors from your App Config alongside many other customizations so it matches the design system of Nuxt UI.

You will be able to wrap your <ContentSlot /> or <ContentRenderer /> with the PageBody component and its prose class to apply the prose prose-primary dark:prose-invert max-w-none classes automatically to your content and make it look great.

To help you when writing content, we've also added some components to use in your .md files using the MDC syntax like a Callout, Card, CodeGroup, Tabs, etc.

Utils

Some utils will be auto-imported to make the bridge between @nuxt/content and @nuxt/ui-pro:

mapContentNavigation

This util will map the navigation from fetchContentNavigation that you'll usually fetch in your app.vue file and transform it recursively into an array of objects expected by components like NavigationTree.

app.vue
<script setup lang="ts">
const { data: navigation } = await useAsyncData('navigation', () => fetchContentNavigation(), { default: () => [] })
</script>

<template>
  <UHeader>
    <template #panel>
      <UNavigationTree :links="mapContentNavigation(navigation)" />
    </template>
  </UHeader>
</template>

findPageHeadline

This util will allow you to bind an headline in the PageHeader based on the page _dir.

pages/[...slug].vue
<script setup lang="ts">
const route = useRoute()

const { data: page } = await useAsyncData(route.path, () => queryContent(route.path).findOne())

const headline = computed(() => findPageHeadline(page.value))
</script>

<template>
  <UPage>
    <UPageHeader v-bind="page" :headline="headline" />
  </UPage>
</template>

findPageBreadcrumb

This util will recursively find the breadcrumb of a page based on the navigation so you can use it in the PageHeader #headline slot.

app.vue
<script setup lang="ts">
const { data: navigation } = await useAsyncData('navigation', () => fetchContentNavigation())

provide('navigation', navigation)
</script>
pages/[...slug].vue
<script setup lang="ts">
import type { NavItem } from '@nuxt/content'

const navigation = inject<Ref<NavItem[]>>('navigation', ref([]))

const route = useRoute()

const { data: page } = await useAsyncData(route.path, () => queryContent(route.path).findOne())

const breadcrumb = computed(() => mapContentNavigation(findPageBreadcrumb(navigation.value, page.value)))
</script>

<template>
  <UPage>
    <UPageHeader v-bind="page">
      <template #headline>
        <UBreadcrumb :links="breadcrumb" />
      </template>
    </UPageHeader>
  </UPage>
</template>

You should have all the informations to start building your app with @nuxt/ui-pro, you can now explore all the available components 🚀