Closed abhisheknaiidu closed 2 years ago
Hey @abhisheknaiidu, good question! Your HTML serializer generally looks good, but I think you could move the <a>
replacements to Elements.span
rather than Element.paragraph
. Elements.span
is the lowest level of the serializer; paragraphs, for example, will contain spans.
The reason you are seeing other hyperlinks being removed is because you are stopping the serializer from reaching the other Element types. This is due to not including children
in your return type.
Here's an example you could try:
const htmlSerializer = function (type, children, element, content, key) {
switch (type) {
case Elements.span: {
if (!content) {
return null
}
// For each keyword, replace the keyword with a link.
let contentWithSEOAnchors = content
for (const keyword of keywords) {
contentWithSEOAnchors.replace(
keyword.text,
`<a href="${keyword.link}">${keyword.text}</a>`,
)
}
// For each new line (`\n`) in the content, replace it with a <br />
// This is done in the default HTML serializer and replicated here.
const result = []
contentWithSEOAnchors.split('\n').forEach((line, index) => {
if (index > 0) {
result.push(<br />)
}
result.push(line)
})
return result
}
default: {
return null
}
}
}
@angeloashmore thanks for replying, so with this I'm able to add the anchor tags to the content tho, but not able to split the function (\n
) in the content, could you see this code . (it's splitting only the manual anchor tags only which were added in Prismic, not splitting the SEO one's) ⬇️
function htmlSerializer(type, element, content, children, key) {
switch (type) {
case Elements.paragraph:
return React.createElement('p', { className: 'paragraph-class' }, children);
case Elements.span: {
if (!content) {
return null
}
// For each keyword, replace the keyword with a link.
let contentWithSEOAnchors = content;
// console.log(content)
for (const keyword of keywords) {
contentWithSEOAnchors = contentWithSEOAnchors.replace(
keyword.text,
`<a href="${keyword.link}">${keyword.text}</a>`,
)
}
// not able to split
const result = []
contentWithSEOAnchors.split('/n').forEach((line, index) => {
console.log(line, index)
if (index > 0) {
result.push(<br />)
}
result.push(line)
})
// console.log(result) thi
return result
}
default:
return null;
}
};
@abhisheknaiidu Sorry, I didn't full test out that example serializer I posted. Could you try this one instead?
function htmlSerializer(type, element, content, children, key) {
switch (element.type) {
case Elements.paragraph:
return (
<p className="paragraph-class" key={key}>
{children}
</p>
);
case Elements.span: {
if (!content) {
return null;
}
// For each keyword, replace the keyword with a link.
let contentWithSEOAnchors = [content];
for (const keyword of keywords) {
contentWithSEOAnchors = contentWithSEOAnchors.map((contentSegment) => {
if (typeof contentSegment === "string") {
const result = [];
contentSegment.split(keyword.text).forEach((segment, index) => {
if (index > 0) {
result.push(
<a key={`br-${index}`} href={keyword.link}>
{keyword.text}
</a>
);
}
result.push(
<React.Fragment key={index}>{segment}</React.Fragment>
);
});
return result.flat();
} else {
return contentSegment;
}
});
}
// For each new line (`\n`) in the content, replace it with a <br />
// This is done in the default HTML serializer and replicated here.
const result = [];
contentWithSEOAnchors.flat().forEach((segment) => {
if (typeof segment === "string") {
segment.split("\n").forEach((line, index) => {
if (index > 0) {
result.push(<br key={`br-${index}`} />);
}
result.push(<React.Fragment key={index}>{line}</React.Fragment>);
});
} else {
result.push(segment);
}
});
return result;
}
default:
return null;
}
}
Hey @abhisheknaiidu, I'm going to close this issue but please feel free to comment if you haven't been able to get this working.
Thanks!
context - I've content in prismic, which already have words hyperlinked, but i want to hyperlink few more words as per SEO, how can i add it using
htmlSerializer
?currently doing this, but it removes the previously hyperlinked words. any solution to resolve this?