Using Prismic with Nuxt.js

This article discusses how to use Prismic with Nuxt.js and how it's different than standard Vue.js. Migrating an old Prismic & Nuxt project? You can read how to do that here.

Why Nuxt?

Nuxt.js is a hugely popular solution within in the Vue.js community when it comes to creating server sider rendered or statically deployed applications.

This community project is built on top of the Vue ecosystem and handles all aspects of a production-ready server side rendered app. Here's a link to learn more about Nuxt.js.

How to set up your Nuxt Project

With the help of James Pegg and the team at Nuxt we worked to create a plugin that makes creating Nuxt apps with Prismic a breeze.

Install dependencies

The first thing to do is install the prismic-nuxt module.

npm i @nuxtjs/prismic

Make sure you're using at least Nuxt 2.11.0

npm upgrade nuxt

Configure your nuxt.config.js file

This file is where all the settings for your Project will go. It is also really important for connecting to Prismic and configuring the prismic-nuxt module. There are a few areas to which you should pay attention.


The most important thing here is to add this module that will enabled you to query prismic easily.

@/modules/static + @/modules/crawler

These modules are for implementing full static deployment in preparation for the nuxt prerender feature (coming in v2.13), adding these now will help future-proof your project and dynamically generate your routes. For now you need to add these files manually as is done in this link.


This is where you add your settings in regards to Prismic, this includes:
This is where you define the link to your Prismic API to get all your content. You'll find your endpoint in your repo settings under the 'API & Security' tab.

Here you can either add directly or import your link resolver for your project. Learn more about what the link resolver does here.


Again here you can either add directly or import your custom HTML serializer. Learn more about the HTML serializer here.


This small setting is for deploying sites statically on Netlify. This fallback will allow the 404 page to be loaded like a SPA so that previewing unpublished articles will function correctly.

Below is a full example of how this file should look.

export default {
  mode: 'universal',

  ** Headers of the page
  head: {
    title: 'Prismic + Nuxt Blog example',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: 'Prismic + Nuxt Blog example' }
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
      { rel: 'stylesheet', href: ',400,700,900' }

  ** Customize the progress-bar color
  loading: { color: '#fff' },

  ** Global CSS
  css: [

  ** Plugins to load before mounting the App
  plugins: [

  ** Nuxt.js modules
  modules: [
    // modules for full static before `nuxt export` (coming in v2.12)
    // This is where you import the new plugin

  // This is where you configure your settings for the new plugin
  prismic: {
    endpoint: '',
    linkResolver: '@/plugins/link-resolver',
    htmlSerializer: '@/plugins/html-serializer',

  ** Build configuration
  build: {
    ** You can extend webpack config here
    extend(config, ctx) {
      config.resolve.alias['vue'] = 'vue/dist/vue.common'

  // Netlify reads a 404.html, Nuxt will load as an SPA
  generate: {
    fallback: '404.html'

Using the Html Serializer

One difference here between Nuxt and Vue is wrapping links from your rich text fields in the <nuxt-link> tag. Below is what a full HTML serializer for a Nuxt.js project should look like.

import linkResolver from "./link-resolver"
import prismicDOM from 'prismic-dom'

const Elements = prismicDOM.RichText.Elements

export default function (type, element, content, children) {
  // Generate links to Prismic Documents as <router-link> components
  // Present by default, it is recommended to keep this
  if (type === Elements.hyperlink) {
    let result = ''
    const url = prismicDOM.Link.url(, linkResolver)

    if ( === 'Document') {
      result = `<nuxt-link to="${url}">${content}</nuxt-link>`
    } else {
      const target = ? `target="'${}'" rel="noopener"` : ''
      result = `<a href="${url}" ${target}>${content}</a>`
    return result

  // If the image is also a link to a Prismic Document, it will return a <router-link> component
  // Present by default, it is recommended to keep this
  if (type === Elements.image) {
    let result = `<img src="${element.url}" alt="${element.alt || ''}" copyright="${element.copyright || ''}">`

    if (element.linkTo) {
      const url = prismicDOM.Link.url(element.linkTo, linkResolver)

      if (element.linkTo.link_type === 'Document') {
        result = `<nuxt-link to="${url}">${result}</nuxt-link>`
      } else {
        const target = ? `target="${}" rel="noopener"` : ''
        result = `<a href="${url}" ${target}>${result}</a>`
    const wrapperClassList = [element.label || '', 'block-img']
    result = `<p class="${wrapperClassList.join(' ')}">${result}</p>`
    return result

  // Return null to stick with the default behavior for everything else
  return null

Querying the API

When getting your content for your documents with Nuxt.js a good practice is to use the asyncData lifecycle function when requesting the data. When you do this you should pass the $prismic (this represents the prismic-nuxt module) & error methods.

You can then create a try/catch block and use the $prismic method to query the API.

In the following example we use the getSingle helper function, as we would in standard Vue.js, to query a singleton type with the API ID of 'homepage'. Then we set the response as document and return the data to be used in the page template.

async asyncData({ $prismic, error }) {
    const document = (await $prismic.api.getSingle('homepage')).data
    return {
  } catch (e) {
    error({ statusCode: 404, message: 'Page not found' })

Things to remember for Nuxt queries

When creating a query inside the asyncData method you cannot use the this keyword. Also when using Prismic Predicates to query your data you must use the all lowercase predicates.

So in the following examples:

this.$'document.type', 'post')

The query becomes:

$"document.type", "post")

All other queries to the API remain the same. You can see these queries here.


Templating your data in Nuxt remains the same as vue.js except for one method where you deliver data from a rich text field as plain unformatted text.

In vue.js you can use richTextAsPlain to do this, but in Nuxt you will have to specify the method asText. You can see an example below which is templating a field with API ID title as plain unformatted text.

{{ $prismic.asText(title) }}

All other templating options are the same as Vue.js you can see this options here. You also have more extra helper functions


Thanks to the prismic-nuxt module creating previews in Nuxt.js is really straightforward as everything is handled for you. All you have to do is set up your preview on the Prismic side.

Deploying your application

We recommend deploying your Nuxt.js and Prismic application with Netlify, but there are lots of other options that the Nuxt website explains in detail.

A full working example project with Nuxt.js

Feel free to explore our fully working example websitex project using Nuxt.js and Prismic.

Nuxt.js & Prismic Example Website