HTML Serializer

You can customize the HTML output of a Rich Text Field by incorporating an HTML Serializer into your project. This allows you to do things like adding custom classes to certain elements or adding a target element to all hyperlinks.

Configuring the HTML Serializer globally.

Thanks to the @nuxt/prismic module, connecting your HTML Serializer is simply by creating a file called html-serializer.js in the folder ~/app/prismic, as described in the module documentation. Like this your Serializer will be applied automatically everywhere.

Adding the HTML Serializer

Below we have a full standard example of a Prismic HTML Serializer, although there is an issue with creating nuxt-links as described here.

Usually when adding a HTML serializer we would want to turn links from the Rich Text into router links so the application isn't reloaded every time an in-app link is clicked, but since the Vue runtime compiler does not support SSR, the <nuxt-link> won't be processed by Nuxt.js.

The workaround

Instead, what we suggest the following:

1. Add a property like data-nuxt-link to <a> tags in your HTML Serializer:

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(element.data, linkResolver)

    if (element.data.link_type === 'Document') {
      result = `<a href="${url}" data-nuxt-link>${content}</a>`
    } else {
      const target = element.data.target ? `target="'${element.data.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.data.link_type === 'Document') {
        result = `<a href="${url}" data-nuxt-link>${result}</a>`
      } else {
        const target = element.data.target ? `target="'${element.data.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
  }

  if (type === Elements.heading2) {
    var id = element.text.replace(/\W+/g, '-').toLowerCase();
    return '<h2 id="' + id + '">' + children.join('') + '</h2>';
  }

  if (type === Elements.heading3) {
    var id = element.text.replace(/\W+/g, '-').toLowerCase();
    return '<h3 id="' + id + '">' + children.join('') + '</h3>';
  }

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

2. Create this file in plugins/prismicLinks.js (This file uses event listeners to push link destinations.)

export default async ({ redirect }) => {
    window.addEventListener(
        'click',
        (event) => {
            // If the clicked element doesn't have the right selector, bail
            if (!event.target.matches('a[data-nuxt-link]')) return

            // Don't follow the link
            event.preventDefault()

            // Push link destination to router
            redirect(event.target.pathname)
        },
        false
    )
}

3. Add the plugin to your nuxt.config.js with ssr set to false:

{
    // ...other configuration
    plugins: [
        // ...other plugins
        { src: '~/plugins/prismicLinks', ssr: false }
    ]
}

Et voilà!... you've got a HTML Serializer which creates nuxt router links and which you can customise until your heart's content.

9 Rue de la Pierre Levée, 75011 Paris