Advanced Rich Text Templating

An HTML Serializer determines how to render Rich Text content in your code. You will learn how to customize your Rich Text output with an HTML Serializer on this page.


Introduction

You can customize the HTML output of a Rich Text Field with a custom HTML Serializer. An HTML Serializer defines how Rich Text content should be interpreted in your code. For instance: the default HTML Serializer dictates that italicized text should be rendered inside <em> tags.

The default HTML Serializer

If your project is configured with Prismic, it should already have a default HTML Serializer integrated. If you would like to add custom formatting, you can add a custom HTML Serializer as needed.

A custom HTML Serializer

The HTML Serializer is a function. It works by taking a Rich Text element and evaluating it through a switch statement to determine how to render it. If your custom HTML Serializer doesn't have a case for the element, it should return null. Then the default HTML Serializer will take over and render the element.

The HTML Serializer receives the following arguments:

  • type: the type of the element, such as "paragraph" or "list-item"
  • element: the complete element, represented as an object
  • content: the string content of the element
  • children: any children contained within the element

You can define a local HTML Serializer and pass it as a property to the RichText component, or you can define a global HTML Serializer to be used automatically on all Rich Text elements.

Using a custom HTML Serializer locally

You can define a simple HTML Serializer in your code like so:

Copy
<template>
  <div>
    <!-- Pass the HTML Serializer to your rich text component. -->
    <prismic-rich-text :field="document.description" :htmlSerializer="htmlSerializer" />
  </div>
</template>

<script>
export default {
  async asyncData({ $prismic, params, error }) {
    const document = await $prismic.api.getSingle("homepage")
    return { document };
  },
  methods: {
    htmlSerializer(type, element, content, children) {
      // If element is a list item,
      if (type === "list-item") {
        // return some customized HTML.
        return `<li class="example-class">${children.join("")}</li>`;
      }
      /// Otherwise, return null.
      return null;
    }
  }
};
</script>

Using a custom HTML Serializer globally

To create a global HTML Serializer, create a file called html-serializer.js in the directory ~/app/prismic/. Create the ~/app/ directory if it doesn't already exist. Your serializer will be used globally. If it returns null, the default HTML Serializer will take effect.

Copy
export default function(type, element, content, children) {
  // If element is a list item,
  if (type === "list-item") {
    // return some customized HTML.
    return `<li class="example-class">${children.join("")}</li>`;
  }
  // Otherwise, return null.
  return null;
}

Rendering Nuxt Links

What's a Link Resolver?

The code snippet below includes a Link Resolver. A Link Resolver is a function that defines the URLs for your content. You can learn more about it in the Link Resolver documentation.

By default, the HTML Serializer cannot generate Nuxt links. Nuxt links facilitate single-page navigation, so you can navigate your site without reloading the page. If you want to render Nuxt links, you can use the following workaround.

First, in your HTML Serializer, add the property data-nuxt-link to your <a> tags.

Copy
import linkResolver from "./path-to-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
  if (type === Elements.hyperlink) {
    const url = prismicDOM.Link.url(element.data, linkResolver)
    if (element.data.link_type === 'Document') {
      return `<a href="${url}" data-nuxt-link>${content}</a>`
    } 
  }

  // If an image links to a Prismic Document, it will return a <router-link> component
  if (type === Elements.image && element.linkTo && element.data.link_type === 'Document') {
      const url = prismicDOM.Link.url(element.linkTo, linkResolver)
      if (element.data.link_type === 'Document') {
        return `<a href="${url}" data-nuxt-link><img src="${element.url}" alt="${element.alt || ''}" copyright="${element.copyright || ''}"></a>`
      }
    }
  }
  // Return null to stick with the default behavior for everything else.
  return null
}

Then, add a plugin by creating the file ~/plugins/prismicLink.js and adding the following code. The plugin uses event listeners to push the client to the linked destination.

Copy
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
  );
};

Finally, add the plugin to your nuxt.config.js with ssr set to false:

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

Et voilà!... you now have an HTML Serializer that creates Nuxt router links.


Related articles


Was this article helpful?
Not really
Yes, Thanks

Can't find what you're looking for? Get in touch with us on our Community Forum.