It looks like what I want to do should be possible, but I don't think I'm getting the syntax quite right. I would like to automatically find and replace special characters like ® with ® and wrap them in tags.
Looking at the video on serializers here https://youtu.be/US6mirW71ac&t=312, it looks like this should be possible with children.replace, but my IDE is not accepting replace on children since that's JSX Elements directly. I do not want to use labels for this because there are already labels in use and since they cannot currently be nested this won't work.
Can you give me a little more information on your code and what it looks like right now, so we're better able to help you out?
What do you mean by that? What are the JSX elements, and what IDE are you using? Are you seeing any error codes or unexpected behaviors related to what you're trying to do?
This error is likely happening because .replace is a method that only works on strings. Because you're passing heading from PrismicRichText as a prop, children is either not a string, or not read as a string, which is what TypeScript is telling you with children is a type 'Element[ ]'. If you want to use .replace for your htmlSerializer, you'd have to make sure of what children is.
Is this your entire serializer just like in the YouTube video, or is this part of a specific slice? If you can show me the rest of your code, or the way that you're going about this, I can try to help you figure it out with or without replace
I also need to wrap some placeholders in the text by some html tags, the case is similar as described by OP.
Unfortunately the accepted solution is not working with latest "@prismicio/react": "2.9.1", "@prismicio/next": "1.7.1", "@prismicio/client": "7.12.0".
Error when using PrismicRichText from @prismicio/react: typeof child === 'string'Invalid 'typeof' check: 'child' cannot have type 'string'
The childern prop available to components?: JSXMapSerializer | JSXFunctionSerializer | undefined is typed as a JSX.Element[] not as a string[]. When debugging, it always looks like an array of JSX Elements with complex structures, not as simple array of strings.
This could be due to the fact that the children prop in the latest versions of Prismic's libraries is always typed as an array of JSX elements (JSX.Element[]) rather than an array of strings or mixed types. This means the typeof child === 'string' check isn't valid because child is never directly a string in this context.
To address this, you can use a recursive approach to traverse the children array and process any text nodes within it. Here's an updated example that should work with the latest versions:
import { PrismicRichText } from "@prismicio/react";
const processChildren = (children) => {
return children.map((child) => {
if (typeof child === 'string') {
// Replace text or wrap placeholders
return child.replace(/(PLACEHOLDER)/g, '<span class="highlight">$1</span>');
} else if (React.isValidElement(child) && child.props?.children) {
// Recursively process nested children
return React.cloneElement(child, {
children: processChildren(React.Children.toArray(child.props.children)),
});
}
return child; // Return unmodified child if it's neither a string nor an element with children
});
};
const MyComponent = ({ slice }) => (
<PrismicRichText
field={slice.primary.content}
components={{
paragraph: ({ children }) => {
const processedChildren = processChildren(children);
return <p>{processedChildren}</p>;
},
heading1: ({ children }) => {
const processedChildren = processChildren(children);
return <h1>{processedChildren}</h1>;
},
}}
/>
);
export default MyComponent;