---
url: /en/docs/frameworks/nuxt.md
description: >-
  Learn how to integrate Sveltia CMS with Nuxt and Nuxt Content, including the
  admin page setup, collection configuration and real-world examples.
---

# Nuxt Integration Guide

This guide provides resources and information for integrating Sveltia CMS with [Nuxt](https://nuxt.com/), a popular Vue.js framework for building server-side rendered and static websites.

## Examples

See real-world examples of Nuxt integrations in our [Showcase](/en/showcase?framework=nuxt). Most of the listed sites include links to their source code, so you can explore how they implemented Sveltia CMS with Nuxt.

## Setup

### Adding the Admin Page

Nuxt serves static files from the [`public` folder](https://nuxt.com/docs/4.x/directory-structure/public). Create `public/admin/index.html` and `public/admin/config.yml` as described in the [Getting Started](/en/docs/start#manual-installation) guide. The admin page is then available at `/admin/` on both the development server and the production site.

If your project still uses Nuxt 2, the static files folder is `static` instead of `public`.

### Linking to the Admin Page

The admin page is not part of your Nuxt app. If you link to it with the `<NuxtLink>` component, add the `external` prop so that Vue Router doesn’t try to render it as a page:

```vue
<NuxtLink to="/admin/" external>Edit content</NuxtLink>
```

A regular `<a href="/admin/">` element works as well.

## Configuration

Most Nuxt sites manage Markdown content with the [Nuxt Content](https://content.nuxt.com/) module, which reads files from the `content` folder. In Nuxt Content v3, the files are grouped into [collections](https://content.nuxt.com/docs/collections/define) defined in `content.config.ts`, and each collection’s front matter can be validated with a [Zod](https://zod.dev/) schema:

```ts [content.config.ts]
import { defineCollection, defineContentConfig } from '@nuxt/content';
import { z } from 'zod';

export default defineContentConfig({
  collections: {
    blog: defineCollection({
      type: 'page',
      source: 'blog/*.md',
      schema: z.object({
        date: z.date(),
        image: z.string().optional(),
        tags: z.array(z.string()).optional(),
      }),
    }),
  },
});
```

The matching Sveltia CMS entry collection uses the folder of the `source` pattern, prefixed with `content/`. `title` and `description` are built-in fields of a `page` collection, so they don’t need to be defined in the schema, but they should be added to the CMS configuration:

```yaml [public/admin/config.yml]
media_folder: public/images
public_folder: /images
output:
  omit_empty_optional_fields: true
collections:
  - name: blog
    label: Blog
    folder: content/blog
    create: true
    fields:
      - { name: title, label: Title }
      - { name: description, label: Description, required: false }
      - { name: date, label: Date, widget: datetime }
      - { name: image, label: Cover Image, widget: image, required: false }
      - { name: tags, label: Tags, widget: list, required: false }
      - { name: body, label: Body, widget: markdown }
```

The [`omit_empty_optional_fields`](/en/docs/data-output#controlling-data-output) output option keeps empty optional fields out of the front matter. Without it, empty fields are saved as an empty string, an empty array or `null` depending on the field type, which may not pass your schema. For example, `z.string().optional()` accepts a missing property but rejects `null`.

## Loading Content

Query a collection with [`queryCollection`](https://content.nuxt.com/docs/utils/query-collection) and render the Markdown body with the [`<ContentRenderer>`](https://content.nuxt.com/docs/components/content-renderer) component. For example, a catch-all page like `app/pages/[...slug].vue` can find the entry whose path matches the current route.

Nuxt Content parses the content files when the site is built, so the site must be rebuilt to reflect content changes made in the CMS. Most hosting services rebuild the site automatically when a commit is pushed to the repository.
