block-content-to-react
block-content-to-react copied to clipboard
Documentation
There is a lot documentation on how to build the sanity cms (https://www.sanity.io/docs) but I coudn't find sufficient documentation on how to use the fetched data on the client side, which describes how to use sanity-io/block-content-to-react library with serializers e.g. types, marks, list, listItem to render custom react components.
Is there a hidden documentation I missed?
+1 on this with attention to React Native and using custom serializers, etc. as well
I find the documentation on the github README confusing as well.
When will the documentation be updated to align with the samples provided in the Sanity starter projects? -- have been trying to make this work under the NextJS e-Commerce starter (sanity.js file) where PortableText along with empty serliazers object -- have put basic h1/h2 tag processing int here and it doesn't work....it doesn't even work when mushed together inside [slug].js in the root directory of the frontend.
This link is also useless https://www.sanity.io/guides/portable-text-internal-and-external-links#render-the-links-with-react-b14f77c2e796
Figured it out
here's my seralizer object in case anyone's looking for some tips to get started
`// Set up Portable Text serialization export const PortableText = createPortableTextComponent({ ...config, // Serializers passed to @sanity/block-content-to-react // (https://github.com/sanity-io/block-content-to-react)
// implement inline icon serializer from https://medium.com/@kimbjrkman/how-to-use-inline-images-in-rich-text-with-sanity-io-c42594baa509
serializers: { types: { // render video block videoEmbed: (props) => { // const { url } = props.node.url;
if (!props.node.url) {
console.log("video props ->", props);
return null;
}
return (
<>
<div class="container px-5 py-24 mx-auto flex flex-wrap">
<div class="flex flex-wrap w-full">
<ReactPlayer url={props.node.url} controls />
</div>
</div>
</>
);
},
// render text blocks
block: (props) => {
const style = props.node.style || "normal";
if (style == "h1") {
return (
<h1 class="sm:text-3xl text-2xl font-medium title-font mb-4 text-gray-900">
{props.children}
</h1>
);
}
if (style == "h2") {
return (
<h2 class="text-2xl font-medium text-gray-900 title-font mb-2">
{props.children}
</h2>
);
}
if (style == "h3") {
return (
<h3 class="title-font font-medium text-gray-900">
{props.children}
</h3>
);
}
if (/^h\d/.test(style)) {
const level = style.replace(/[^\d]/g, "");
return React.createElement(`h${level}`, {}, props.children);
}
return style === "blockquote" ? (
<blockquote>– {props.children}</blockquote>
) : (
<p class="leading-relaxed">{props.children}</p>
);
},
// render code block
code: (props) => (
<pre data-language={props.node.language}>
<code>{props.node.code}</code>
</pre>
),
// render image
mainImage: (props) => (
<figure>
<img
src={urlFor(props.node.asset)
.auto("format")
.width(500)
// .height(400)
//.fit("crop")
.quality(80)
.url()}
alt={props.node.alt}
/>
<figcaption>{props.node.caption}</figcaption>
</figure>
),
},
list: (props) =>
// console.log("list", props) ||
props.type === "bullet" ? (
<ul>{props.children}</ul>
) : (
<ol>{props.children}</ol>
),
listItem: (props) =>
console.log("list", props) ||
(props.type === "bullet" ? (
<li>{props.children}</li>
) : (
<li>{props.children}</li>
)),
marks: {
strong: (props) =>
console.log("strong", props) || <strong>{props.children}</strong>,
em: (props) => console.log("em", props) || <em>{props.children}</em>,
code: (props) =>
console.log("code", props) || <code>{props.children}</code>,
externalLink: (props) => {
return (
<Link href={props.mark.url}>
<a class="mr-5 hover:text-gray-900 cursor-pointer">
{props.children}
</a>
</Link>
);
},
},
}, });`
Closing this, as the new @portabletext/react
library is the successor to this module.
Please see https://github.com/portabletext/react-portabletext