Use Nuxt with Prismic
Last updated
Overview
Prismic has a first-party Nuxt integration that supports all of Prismic’s features:
- Model content with page types and slices using the Type Builder or the Prismic CLI.
- Fetch and display content using SDKs with generated TypeScript types.
- Preview draft content with live previews and full-website previews.
Here’s what a Prismic page looks like in Nuxt:
<script setup lang="ts">
import { components } from "~/slices";
// 1. Fetch a page from Prismic
const prismic = usePrismic();
const route = useRoute();
const { data: page } = await useAsyncData(route.params.uid as string, () =>
prismic.client.getByUID("page", route.params.uid as string),
);
</script>
<template>
<main>
<!-- 2. Display the page's slices -->
<SliceZone :slices="page?.data.slices ?? []" :components="components" />
</main>
</template>Nuxt websites use @nuxtjs/prismic, @prismicio/client, and @prismicio/vue.
Set up a Nuxt website
Prismic can be added to new or existing Nuxt websites. Set up your project using the Type Builder, a tool for building by hand, or the Prismic CLI, a tool for AI agents.
Set up your project
Follow the setup instructions shown in your Prismic repository. The instructions walk you through creating a Nuxt project, connecting it to Prismic, and modeling content with the Type Builder.
Add the
@nuxtjs/prismicmoduleSetup adds
@nuxtjs/prismicto yournuxt.config.ts. The module reads yourprismic.config.jsonto register the Prismic client, draft preview routing, and auto-imports for Prismic Vue components.nuxt.config.tsexport default defineNuxtConfig({ modules: ["@nuxtjs/prismic"], });Your Nuxt website is now ready for Prismic. Continue to create pages and slices.
Create a Nuxt project
npx nuxi@latest init my-website cd my-websiteYou can also use an existing Nuxt project.
Add Prismic to your project
The
initcommand creates a Prismic repository, installs packages, and configures your project.npx prismic initIf you already have a Prismic repository, provide its domain with
--repo:npx prismic init --repo your-domainConfigure the
@nuxtjs/prismicmoduleprismic initadds@nuxtjs/prismicto yournuxt.config.ts. The module registers the Prismic client, draft preview routing, and auto-imports for Prismic Vue components.nuxt.config.tsimport prismicConfig from "./prismic.config.json"; export default defineNuxtConfig({ modules: ["@nuxtjs/prismic"], prismic: { endpoint: prismicConfig.repositoryName, clientConfig: { routes: prismicConfig.routes, }, }, });Your Nuxt website is now ready for Prismic. Continue to create pages and slices.
Create pages
Content writers create pages from page types, like a homepage, blog post, or landing page. Model page types by hand in the Type Builder, or with the Prismic CLI for AI agents. TypeScript types are generated automatically.
Learn how to create page types
Write page components
Each page type needs a Nuxt page component. With file-system-based routing, you create a page file at each page’s path.
The example below shows a page component for a Page page type.
<script setup lang="ts">
import { components } from "~/slices";
const prismic = usePrismic();
const route = useRoute();
const { data: page } = await useAsyncData(route.params.uid as string, () =>
prismic.client.getByUID("page", route.params.uid as string),
);
useSeoMeta({
title: page.value?.data.meta_title ?? undefined,
description: page.value?.data.meta_description ?? undefined,
ogImage: computed(() => prismic.asImageSrc(page.value?.data.meta_image)),
});
</script>
<template>
<main>
<SliceZone :slices="page?.data.slices ?? []" :components="components" />
</main>
</template>Define routes
The Prismic CLI keeps routes in prismic.config.json in sync with your page types, whether you model in the Type Builder or with CLI commands.
Page routes are inferred from each page type’s API ID:
- A page type named Homepage maps to
/. - A page type named Page maps to
/:uid. - Any other page type, like Blog Post, maps to
/<api-id>/:uid(e.g./blog-post/:uid).
{
"repositoryName": "example-prismic-repo",
"routes": [
{ "type": "homepage", "path": "/" },
{ "type": "page", "path": "/:uid" },
{ "type": "blog_post", "path": "/blog/:uid" }
]
}Edit prismic.config.json directly to customize routes. Make sure your routes match your Nuxt file-system routes. Here are common examples:
| Prismic route | Nuxt file-system route |
|---|---|
/ | pages/index.vue |
/:uid | pages/[uid].vue |
/blog/:uid | pages/blog/[uid].vue |
/:grandparent/:parent/:uid | pages/[...path].vue |
Create slices
Content writers build pages from reusable sections called slices, like a block of text, a hero, or a call to action. Model slices by hand in the Type Builder, or with the Prismic CLI for AI agents. TypeScript types are generated automatically.
Learn how to create slices
Write Vue components
The Prismic CLI generates a starter component in ~/slices/<SliceName>/index.vue. Edit the component to add your implementation.
The following example Call to Action component displays a rich text field and a link.
<script setup lang="ts">
import type { Content } from "@prismicio/client";
defineProps(getSliceComponentProps<Content.CallToActionSlice>());
</script>
<template>
<section class="flex flex-col gap-4 p-8">
<PrismicRichText :field="slice.primary.text" />
<PrismicLink :field="slice.primary.link" class="button" />
</section>
</template>Learn how to display content
Fetch content
Use @prismicio/client and its methods to fetch page content.
The Prismic client
The Prismic CLI keeps your prismic.config.json in sync with the Type Builder. @nuxtjs/prismic reads from it via the clientConfig option in nuxt.config.ts, which centralizes your client configuration.
import prismicConfig from "./prismic.config.json";
export default defineNuxtConfig({
modules: ["@nuxtjs/prismic"],
prismic: {
endpoint: prismicConfig.repositoryName,
clientConfig: {
routes: prismicConfig.routes,
},
},
});Fetch content in pages and slices
Call the usePrismic composable to access the client. Use the client to fetch content. The following example fetches content for a /[uid] dynamic route.
<script setup lang="ts">
import { components } from "~/slices";
const prismic = usePrismic();
const route = useRoute();
const { data: page } = await useAsyncData(route.params.uid as string, () =>
prismic.client.getByUID("page", route.params.uid as string),
);
</script>
<template>
<main>
<SliceZone :slices="page?.data.slices ?? []" :components="components" />
</main>
</template>You can fetch content in slices the same way. The following example fetches a Settings page.
<script setup lang="ts">
import { components } from "~/slices";
const prismic = usePrismic();
const { data: page } = await useAsyncData("settings", () =>
prismic.client.getSingle("settings"),
);
// ...
</script>Learn more about fetching content
Secure with an access token
Published content is public by default. You can require a private access token to secure the API.
Learn more about content visibility
Generate an access token
npx prismic token createSave the new access token as an environment variable in a
.envfile..envNUXT_PUBLIC_PRISMIC_ACCESS_TOKEN=my-access-tokenAccess tokens can also be managed in your repository at Settings → API & Security.
Pass the access token to your client
Provide the token via the
accessTokenoption inclientConfig:nuxt.config.tsexport default defineNuxtConfig({ modules: ["@nuxtjs/prismic"], prismic: { endpoint: prismicConfig.repositoryName, clientConfig: { accessToken: process.env.NUXT_PUBLIC_PRISMIC_ACCESS_TOKEN, routes: prismicConfig.routes, }, }, });Change your repository’s API access
Set the API access to private. Content API requests will immediately require an access token.
npx prismic repo set-api-access privateAPI visibility can also be managed in your repository at Settings → API & Security.
Display content
Display content using @prismicio/vue. Here are the most commonly used components:
<PrismicLink>- Display links using<NuxtLink>.<PrismicImage>- Display images.<PrismicRichText>- Display rich text.<PrismicText>- Display plain text.<SliceZone>- Display slices.
All Prismic components are automatically available in your Nuxt app through auto-imports.
Learn how to display content from a field
Live previews in the Page Builder
The Page Builder shows live-updating thumbnails for each slice as content writers edit.

A page with live previews in the Page Builder.
Live previews are powered by the slice simulator, a special route that renders individual slices. The Prismic CLI creates the simulator page at pages/slice-simulator.vue when you run prismic init.
Tell Prismic where your simulator is running so the Page Builder can load it:
npx prismic preview set-simulator http://localhost:3000The simulator URL can also be set from any document. Click the ”…” button next to the Publish/Unpublish button in the top-right corner and select Live preview settings.
Once your website is deployed, update the simulator URL to your production domain.
Preview draft content
Full-website previews let content writers see draft content on your website before publishing. The @nuxtjs/prismic module registers the /preview route automatically once it’s added to nuxt.config.ts.
Add a development preview URL so you can preview drafts locally:
npx prismic preview add http://localhost:3000/preview --name DevelopmentOnce deployed, add your production URL as a second preview. Previews can also be managed at Settings → Previews.
Deploy
Deploy your Nuxt website with your hosting provider:
Handle content changes
If you deploy your website with nuxt generate, it needs to rebuild when content changes in Prismic. Follow the instructions in our webhooks documentation for your hosting provider.
Register the rebuild endpoint as a webhook so Prismic calls it when content is published or unpublished:
npx prismic webhook create https://example.com/your-rebuild-endpoint \
--trigger documentsPublished \
--trigger documentsUnpublishedWebhooks can also be managed at Settings → Webhooks.
SEO
Page types automatically include fields in an SEO & Metadata tab:
meta_title: The page’s title.meta_description: The page’s description.meta_image: A preview image when your page is shared on social platforms.
Use the metadata fields with the useSeoMeta composable inside your page component.
<script setup lang="ts">
const prismic = usePrismic();
const route = useRoute();
const { data: page } = await useAsyncData(route.params.uid as string, () =>
prismic.client.getByUID("page", route.params.uid as string),
);
useSeoMeta({
title: page.value?.data.meta_title ?? undefined,
description: page.value?.data.meta_description ?? undefined,
ogImage: computed(() => prismic.asImageSrc(page.value?.data.meta_image)),
});
</script>Internationalization
Prismic supports multi-lingual websites. See Locales for details on locale management.
Add locales to your repository
Use the Prismic CLI to add locales.
npx prismic locale add fr-frLocales can also be managed in your repository at Settings → Translations & Locales.
Add the
@nuxtjs/i18nmoduleThe
@nuxtjs/i18nmodule is needed to support internationalization.npx nuxi@latest module add i18nConfigure
@nuxtjs/i18ninnuxt.config.tsIn your project’s
nuxt.config.tsfile, configure thei18noption with your Prismic repository’s locales.nuxt.config.tsexport default defineNuxtConfig({ modules: ["@nuxtjs/prismic", "@nuxtjs/i18n"], prismic: { /* ... */ }, i18n: { locales: ["en-us", "fr-fr"], defaultLocale: "en-us", }, });Fetch content from the visitor’s locale
In your page files, forward the
langparameter to your Prismic query.~/pages/[uid].vue<script setup lang="ts"> const { locale } = useI18n(); const prismic = usePrismic(); const route = useRoute(); const { data: page } = await useAsyncData( `${locale.value}/${route.params.uid}`, () => prismic.client.getByUID("page", route.params.uid as string, { lang: locale.value, }), ); </script>
