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
}
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;
}
};
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.
@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.
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!