Use Nuxt with Prismic
Last updated
Overview
Prismic has a first-party Nuxt integration that supports all of Prismic’s features:
- Model content with slices and page types using Slice Machine.
- 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. Follow these steps to set up a Nuxt project.
Create a Prismic repository
From the Prismic dashboard, create a Prismic repository. Select Nuxt.

When asked to select a starter, select Connect your own web app.
If you prefer starting with a template, select Minimal starter or Full website demo instead.
Set up a Nuxt project
Follow the setup instructions shown in your Prismic repository.

The instructions guide you through creating a new Nuxt project (if needed) and adding Prismic using
@slicemachine/init.The
@slicemachine/initcommand installs Prismic’s packages and configures your project with a Prismic client, content previews, and a Nuxt module.Set up content previews
Content writers can preview content on your website before publishing.
@slicemachine/initperforms most of the setup for you. However, there are a few steps to complete manually.See the preview setup instructions
Start building with Prismic
Your Nuxt website is now ready for Prismic. Next, learn how to create pages and slices.
Create pages
Website pages are managed in Prismic using page types. Page types are created in Slice Machine.
Learn how to create page types
Write page components
Each page type needs a Nuxt page component. With Nuxt’s 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
Prismic needs to know your website’s routes to fill in link URLs. Configure the Nuxt module’s clientConfig.routes option in nuxt.config.ts with a set of route resolvers.
This example includes routes for a homepage, general pages, and a blog.
export default defineNuxtConfig({
modules: ["@nuxtjs/prismic"],
prismic: {
endpoint: "example-prismic-repo",
clientConfig: {
// `type` is the API ID of a page type.
// `path` determines the URL for a page of that type.
routes: [
{ type: "homepage", path: "/" },
{ type: "page", path: "/:uid" },
{ type: "blog_post", path: "/blog/:uid" },
],
},
},
});Your route resolvers should match your Nuxt file-system-based routes. Here are some commonly used routes:
| Route resolver path | Nuxt file-system route |
|---|---|
/ | pages/index.vue |
/:uid | pages/[uid].vue |
/blog/:uid | pages/blog/[uid].vue |
/:grandparent/:parent/:uid | pages/[...path].vue |
Learn more about route resolvers
Create slices
Page content is written using reusable page sections called slices. Slices are created in Slice Machine.
Learn how to create slices
Write Vue components
Slice Machine generates a bootstrapped Vue component when a slice is created. You can find the generated files in ~/slices or whichever slice library was selected.
Once your slice is configured with fields, edit the slice’s index.vue file to display the slice’s content.
Here is an example of a Call to Action slice. It displays a rich text field and a link field.
<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.
Configure the module’s Prismic client
@nuxtjs/prismic creates a Prismic client using the module’s configuration. You can configure it further using the clientConfig option in nuxt.config.ts.
This example configures the client with an access token.
export default defineNuxtConfig({
modules: ["@nuxtjs/prismic"],
prismic: {
endpoint: "example-prismic-repo",
clientConfig: {
accessToken: "example-access-token",
},
},
});Fetch content in pages and slices
Call the usePrismic composable to access the client. Use the client to fetch content.
This example page 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. This 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
Open your API & Security settings
Navigate to your Prismic repository and go to Settings > API & Security.

The API & Security settings in a Prismic repository.
Change the API access
Under the Repository security section, change the API access dropdown to “Private API.”
Click Change the API visibility.
Generate an access token
Under the Generate an Access Token section, fill out the form.
Field Value Name A name to identify your website. Callback URL Leave blank. Click Add this application.
Pass the access token to your client
Save the access token as an environment variable in a
.envfile..envPRISMIC_ACCESS_TOKEN=my-access-tokenThen, pass the access token to
clientConfiginnuxt.config.ts.nuxt.config.tsexport default defineNuxtConfig({ modules: ["@nuxtjs/prismic"], prismic: { endpoint: "example-prismic-repo", clientConfig: { accessToken: process.env.PRISMIC_ACCESS_TOKEN, }, }, });The Client ID and Secret values on the API & Security page can be ignored.
Display content
Prismic content can be displayed using @prismicio/vue.
Here are the most commonly used components in Nuxt websites:
<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
Content writers can preview content live while editing in the Page Builder. Each slice in a page is shown as a live-updating thumbnail.

A page with live previews in the Page Builder.
Set up live previewing
Live previews require a special /slice-simulator route in your Nuxt website.
Create a page at
/slice-simulatorCreate a file at
pages/slice-simulator.vuewith the following contents.~/pages/slice-simulator.vue<script setup lang="ts"> import { components } from "~/slices"; </script> <template> <SliceSimulator v-slot="{ slices }"> <SliceZone :slices="slices" :components="components" /> </SliceSimulator> </template>Set the simulator URL in the Page Builder
Navigate to your Prismic repository and open a page.
Click the ”…” button next to the Publish/Unpublish button in the top-right corner. Select Live preview settings.

The live preview settings menu option.
In the modal, enter
http://localhost:3000/slice-simulatorand click Save.
Preview draft content
Content writers can preview content on your website before publishing.
@nuxtjs/prismic performs most of the setup for you. However, there are a few steps to complete manually.
Set up previews in Prismic
After setting up your Nuxt project, set up previews in Prismic.
Open your preview settings
Navigate to your Prismic repository and go to Settings > Previews.

The previews settings page.
Create a preview
In the Manage your previews section, create a preview using the following values:
Field Value Site name Development Domain for your application http://localhost:3000Preview route /previewor the route configured innuxt.config.tsClick Create my preview.
Deploy
To deploy your website, follow the instructions for deploying Nuxt with your chosen hosting provider:
Handle content changes
Your app needs to be rebuilt when your content changes in Prismic.
Follow the instructions in our webhooks documentation for your hosting provider.
SEO
Prismic websites can be optimized for search engines using meta_title and meta_descriptions fields. These fields provide metadata and may improve your website’s ranking.
Add SEO fields to your page types
SEO fields are added to page types by default in an SEO tab.
If your page type does not have this tab, create a tab named SEO and add the following fields:
Label API ID Type Description Meta Title meta_titleRich Text The title shown in search results. Meta Description meta_descriptionText The description shown in search results. Meta Image meta_imageImage The image shown in link previews. The
meta_imagefield is not typically used by search engines, but it can be used as a preview when linking to your website on some platforms.Add metadata to pages
Use the metadata fields with
useSeoMetacomposable.~/pages/[uid].vue<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 websites with multiple languages.
To learn more about Prismic’s locale management, see 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>
Configure Slice Machine
Slice Machine can be configured in slicemachine.config.json. Add options to the adapter.options property.
{
"repositoryName": "example-prismic-repo",
"libraries": ["./src/slices"],
"localSliceSimulatorURL": "http://localhost:3000/slice-simulator",
"adapter": {
"resolve": "@slicemachine/adapter-nuxt",
"options": {
"typescript": true
}
}
}lazyLoadSlicesbooleanDetermines if slice components are lazy loaded with
defineAsyncComponent.
truetypescriptbooleanDetermines if generated files are written in TypeScript or JavaScript.
true if a project has a tsconfig.json file, false otherwise.
generatedTypesFilePathstringThe filepath at which generated TypeScript types will be saved.
prismicio-types.d.tsenvironmentVariableFilePathstringThe filepath at which the active Prismic environment is stored as an environment variable.
.env.local