Nofollow hyperlinks within richtext

There is some documentation here about how to set nofollow on link documents:

However this article doesn't cover what I suspect is the main user case, which is setting nofollow on links within text objects.

I also found this community question with the same issue. The suggested solution is to add a custom label to the text object, which I have done.

I have exactly the same problem as the poster above. I've set the label on my link and have this html element

<span class="nofollow">
<a href="https://www.exmaple.com" target="'_blank'" rel="noopener">Example</a>
</span> 

I'm using Vue and I have the html-serializer setup form the default project. The problem I have now is that I cannot access the anchor element. For example, I can access the span element like this:

if (type === Elements.span) {
    console.log(element);
  }

But how do I access the a element? The children parameter is empty and the element parameter has nothing in I can see that would allow me to access the a element. I also cannot find a way to access the span class.

Here is my whole serializer

/**
 * To learn more about HTML Serializer check out the Prismic documentation
 * https://prismic.io/docs/vuejs/beyond-the-api/html-serializer
 */

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

const Elements = prismicDOM.RichText.Elements

export default function (type, element, content, children) {


  if (type === Elements.heading1) {
    var id = children.toString().toLowerCase().replace(/ /g, '');
    return `<h1 id="${id}">${children}</h1>`;
  }

  if (type === Elements.heading2) {
    var id = children.toString().toLowerCase().replace(/ /g, '');
    return `<h2 id="${id}">${children}</h2>`;
  }

  if (type === Elements.span) {
    console.log(element);
  }

  // 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 = `<router-link to="${url}">${content}</router-link>`
    } 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.linkTo.link_type === 'Document') {
        result = `<router-link to="${url}">${result}</router-link>`
      } else {
        const target = element.linkTo.target ? `target="${element.linkTo.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
}

Any help available on this one? Thanks in advance...

Hello Eve,

Welcome to the Prismic Forum.

If I understood your case, you want to add rel attribute with the value nofollow (rel="nofollow") in all anchor elements presented in Richtext.
You can do it directly on the front end without adding the attribute in prismic. I have written the following sample code to satisfy this need:

// -- Function to add unique key to props
const propsWithUniqueKey = function (props, key) {
  return Object.assign(props || {}, { key });
};

// -- HTML Serializer
// This function will be used to change the way the HTML is loaded
export const htmlSerializer = function (type, element, content, children, key) {
  var props = {};

  switch (type) {
    // Add a class to hyperlinks
    case Elements.hyperlink:
      const targetAttr = element.data.target
        ? { target: element.data.target }
        : {};
      const relAttr = element.data.target ? { rel: "nofollow" } : {};
      props = Object.assign(
        {
          className: "link-class",
          href: element.data.url || linkResolver(element.data),
        },
        targetAttr,
        relAttr
      );
      return React.createElement("a", propsWithUniqueKey(props, key), children);
    // Return null to stick with the default behavior
    default:
      return null;
  }
};

Here is the reference for complete HTMLseralizer:HTML Serializer with Vue.js - Prismic

Let me know if you have any doubt.

Thanks,

Priyanka

Hi, thanks for the response. My use case is that I have a blog (so there are many documents of type blog). This solution would cause all links in every blog to be "nofollow". I want to be able to choose dofollow or nofollow links on a case by case basis.

Hello Eve,

I tried to have any workaround for this use case but It's not possible with the HTML serializer.

Priyanka

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Is this already possible?

Your link text

No-follow link

Your link text

It's just adding that little bit of HTML optionally?

@jelle you can do this by adding labels directly in your content model’s JSON file (please note that as of right now Slice Machine doesn’t support configuring them in the UI yet). Once added, you can handle them using a custom component to check for specific labels and render the format that you need for each link

Thank you for reminding me about the labels. @Pau, could you assist with properly typing the node parameter? I've looked for any prebuilt Prismic types, but I have failed. Your assistance is greatly appreciated.

Hi @nf_mastroianni, label nodes are typed as RTLabelNode: prismic-client/src/types/value/richText.ts at 5b0cd60f6ec833ca0905847b4304a2266bf97f7b · prismicio/prismic-client · GitHub

You can import it like this:

import { RTLabelNode } from "@prismicio/client";

You shouldn't need to use the type directly if you are using the <PrismicRichText> component or asHTML(); the component override should automatically type the node argument. Let us know if you have any other questions about it! :slight_smile: