I've implemented Sanity CMS into Eleventy, and have a working 11ty filter that converts Portable Text to HTML.
I have a fair number of custom blocks, and therefore I'm also passing serializers. However, I am incapable of making one of those serializers work.
Here is my code:
On .eleventy.js
// Portable Text to HTML Filter for Sanity
eleventyConfig.addFilter('sanityToHTML', function(value) {
return blocksToHtml({
blocks: value,
serializers: serializers
})
})
On serializers.js
const { h } = require("@sanity/block-content-to-html");
module.exports = {
types: {
cta: ({ node }) => {
return h(
'a',
{
className:
'bg-yellow-500 text-white',
href: node.ctaUrl,
},
node.ctaText,
)
},
infoText: ({ node }) => {
return h(
'p',
{
className:
'bg-blue-500 text-white',
},
node.bodyInfo.map(children => children.text).join(''),
)
},
},
}
Eleventy is oputputting the <p class="bg-blue-500 text-white"></p>
, but without content.
I've tried all combinations that I can think of.
My Sanity blog post has the following structure:
{
"_createdAt": "2021-09-14T11:25:05Z",
"_id": "89ff5403-326b-4db1-8752-04ea1c85f114",
"_rev": "7dkOKJtWoyCn0kHUhHzZu7",
"_type": "post",
"_updatedAt": "2021-09-20T06:38:14Z",
"body": [
{
"_key": "f84e932860bf",
"_type": "block",
"children": [
{
"_key": "bd29bce1dda1",
"_type": "span",
"marks": [],
"text": ""
}
],
"markDefs": [
{
"_key": "38aa715c6214",
"_type": "link",
"href": "........"
}
],
"style": "normal"
},
{
"_key": "bf5d17f3da91",
"_type": "cta",
"ctaText": "test",
"ctaUrl": ".........."
},
{
"_key": "595873ddfc54",
"_type": "block",
"children": [
{
"_key": "ba794ddbef68",
"_type": "span",
"marks": [],
"text": ""
}
],
"markDefs": [
{
"_key": "38aa715c6214",
"_type": "link",
"href": ".........."
}
],
"style": "normal"
},
{
"_key": "8acb94638c0c",
"_type": "infoText",
"bodyInfo": [
{
"_key": "6b6e533e67fd",
"_type": "block",
"children": [
{
"_key": "3593ad3abdf9",
"_type": "span",
"marks": [],
"text": "test test info"
}
],
"markDefs": [],
"style": "normal"
}
]
},
.....etc
Any tips on how to make it display the actual content?
I believe the issue is in your infoText
serializer. In that function, you're mapping over node.bodyInfo
and then accessing the text
property on the objects in bodyInfo
. However, the objects in bodyInfo
do not actually have a text
property.
{
"_key": "8acb94638c0c",
"_type": "infoText",
"bodyInfo": [
{
"_key": "6b6e533e67fd",
"_type": "block",
"children": [
{
"_key": "3593ad3abdf9",
"_type": "span",
"marks": [],
"text": "test test info"
}
],
"markDefs": [],
"style": "normal"
}
]
}
The string you are trying to extract is at bodyInfo[].children[].text
, not bodyInfo[].text
. To fix this, you might want to update your infoText
serializer.
infoText: ({ node }) => {
return h(
'p',
{
className: 'bg-blue-500 text-white',
},
node.bodyInfo.map(({children}) => children.map(child => child.text)).flat().join(''),
)
}
In this version, we first map over bodyInfo
, which is an array, then destructure the children
property from the objects within. We then map over that to get our inner strings, then flatten the array to join.