HTML Serializer in Javascript

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.

Before Reading

In order for the following HTML Serializer examples to work, you must make sure that your project is using the prismic-dom version 2.1.0 or higher. This will not work for older versions of the kit.

Adding the HTML Serializer function

To be able to modify the HTML output of a Rich Text, you need to first create the HTML Serializer function.

It will need to identify the element by type and return the desired output.

Make sure to add a default case that returns null. This will leave all the other elements untouched.

Here is an example of an HTML Serializer that will prevent image elements from being wrapped in paragraph tags and add a custom class to all hyperlink and paragraph elements.

Copy
var PrismicDOM = require('prismic-dom');
var Elements = PrismicDOM.RichText.Elements;

var htmlSerializer = function (type, element, content, children) {
  switch(type) {

    // Add a class to paragraph elements
    case Elements.paragraph:
      return '<p class="paragraph-class">' + children.join('') + '</p>';

    // Don't wrap images in a <p> tag
    case Elements.image:
      return '<img src="' + element.url + '" alt="' + element.alt + '">';

    // Add a class to hyperlinks
    case Elements.hyperlink:
      var target = element.data.target ? 'target="' + element.data.target + '" rel="noopener"' : '';
      var linkUrl = PrismicDOM.Link.url(element.data, linkResolver);
      return '<a class="some-link"' + target + ' href="' + linkUrl + '">' + content + '</a>';

    // Return null to stick with the default behavior for all other elements
    default:
      return null;
  }
};

Note that if you are using the API v2 and want to change the output for the hyperlink element, you will need to input a Link Resolver. You can read more about this on the Link Resolving page.

Using the serializer function

To use it, all you need to do is pass the Serializer function into the asHtml method for a Rich Text element. Make sure to pass it in as the third parameter, the first being for the content field in the response object and the second being for the Link Resolver.

Copy
var PrismicDOM = require('prismic-dom');

PrismicDOM.RichText.asHtml(document.data.body, linkResolver, htmlSerializer)

Example with all elements

Here is an example that shows you how to change all of the available Rich Text elements.

Copy
var PrismicDOM = require('prismic-dom');
var Elements = PrismicDOM.RichText.Elements;

var htmlSerializer = function (type, element, content, children) {
  switch(type) {
    case Elements.heading1: return `<h1>${children.join('')}</h1>`;
    case Elements.heading2: return `<h2>${children.join('')}</h2>`;
    case Elements.heading3: return `<h3>${children.join('')}</h3>`;
    case Elements.heading4: return `<h4>${children.join('')}</h4>`;
    case Elements.heading5: return `<h5>${children.join('')}</h5>`;
    case Elements.heading6: return `<h6>${children.join('')}</h6>`;
    case Elements.paragraph: return `<p>${children.join('')}</p>`;
    case Elements.preformatted: return `<pre>${children.join('')}</pre>`;
    case Elements.strong: return `<strong>${children.join('')}</strong>`;
    case Elements.em: return `<em>${children.join('')}</em>`;
    case Elements.listItem: return `<li>${children.join('')}</li>`;
    case Elements.oListItem: return `<li>${children.join('')}</li>`;
    case Elements.list: return `<ul>${children.join('')}</ul>`;
    case Elements.oList: return `<ol>${children.join('')}</ol>`;
    case Elements.image:
      var linkUrl = element.linkTo ? PrismicDOM.Link.url(element.linkTo, module.exports.linkResolver) : null;
      var linkTarget = element.linkTo && element.linkTo.target ? `target="${element.linkTo.target}" rel="noopener"` : '';
      var wrapperClassList = [element.label || '', 'block-img'];
      var img = `<img src="${element.url}" alt="${element.alt || ''}" copyright="${element.copyright || ''}">`;
      return (`
        <p class="${wrapperClassList.join(' ')}">
          ${linkUrl ? `<a ${linkTarget} href="${linkUrl}">${img}</a>` : img}
        </p>
      `);
    case Elements.embed:
      return (`
        <div data-oembed="${element.oembed.embed_url}"
          data-oembed-type="${element.oembed.type}"
          data-oembed-provider="${element.oembed.provider_name}"
        >
          ${element.oembed.html}
        </div>
      `);
    case Elements.hyperlink:
      var target = element.data.target ? `target="${element.data.target}" rel="noopener"` : '';
      var linkUrl = PrismicDOM.Link.url(element.data, linkResolver);
      return `<a ${target} href="${linkUrl}">${children.join('')}</a>`
    case Elements.label:
      var label = element.data.label ? ` class="${element.data.label}"` : '';
      return `<span ${label}>${children.join('')}</span>`;
    case Elements.span: return content ? content.replace(/\n/g, "<br />") : '';
    default: return null;
  }
};