Describe your question/issue in detail
I'm using Svelte 4.2.17
I needed to apply custom styling to the rich text fields. Doing straight text content works fine, but when the content is slightly more complex (list items with spans), I'm only able to get the text for each list item.
Below is the errant code in richTextSerializer.js (Full code also provided):
This works, but only displays the text:
list: (node) => {
console.log('list:', { node });
const listItems = node.node.items.map(item => {
const content = item.text;
console.log('listItem:', content);
return `<li>${content}</li>`;
}).join('');
return `<ul class="list-disc">${listItems}</ul>`;
}
This does not work. Getting RangeError: Maximum call stack size exceeded:
list: (node, type) => {
console.log('list:', {node});
const listItems = node.node.items.map(item => {
const content = prismicR.serialize([{ ...item, type: 'list-item' }], richTextSerializer);
console.log('listItem:', content);
return `<li>${content}</li>`;
}).join('');
return `<ul class="list-disc">${listItems}</ul>`;
},
Full code:
richTextSerializer.js
import { prismicH } from '$lib/prismicio.js';
import * as prismicR from '@prismicio/richtext';
export const richTextSerializer = prismicR.wrapMapSerializer({
heading1: (type, node, content) => {
return `<h1 class="mb-4 font-bold text-regal-blue text-5xl">${content}</h1>`;
},
heading2: (type, node, content) => {
return `<h2 class="mb-4 font-bold text-regal-blue text-4xl">${content}</h2>`;
},
heading3: (type, node, content) => {
return `<h3 class="mb-4 font-bold text-regal-blue text-3xl">${content}</h3>`;
},
// list: (node, type) => {
// console.log('list:', {node});
// const listItems = node.node.items.map(item => {
// const content = prismicR.serialize([{ ...item, type: 'list-item' }], richTextSerializer);
// console.log('listItem:', content);
// return `<li>${content}</li>`;
// }).join('');
// return `<ul class="list-disc">${listItems}</ul>`;
// },
list: (node) => {
console.log('list:', { node });
const listItems = node.node.items.map(item => {
const content = item.text;
console.log('listItem:', content);
return `<li>${content}</li>`;
}).join('');
return `<ul class="list-disc">${listItems}</ul>`;
},
paragraph: (type, node, content) => {
console.log('paragraph:', { type });
return `<p class="text-cyan">${type.text}</p>`;
},
'list-item': (type, node, content) => {
console.log('list-item:', { type });
return `<li>${type.node.items}</li>`;
},
});
export const asHTML = (richText) => {
return prismicR.serialize(richText, richTextSerializer).join('');
};
BasicGrid/index.svelte
<script>
import { PrismicImage } from '@prismicio/svelte';
import { asHTML } from '$lib/richTextSerializer';
/** @type {import("@prismicio/client").Content.BasicGridSlice} */
export let slice;
</script>
<section data-slice-type={slice.slice_type} data-slice-variation={slice.variation}
class="section--description heal-process container mx-auto px-3 py-16 sm:px-0 relative bg-white">
<div class="container mx-auto">
<h2 class="mb-4 font-bold text-regal-blue text-4xl">{slice.primary.grid_title}</h2>
<div class="grid grid-cols-2 place-content-evenly">
<div id="description" class="pe-4">
{@html asHTML(slice.primary.grid_content)}
</div>
<PrismicImage field={slice.primary.grid_image} class="block mx-auto" />
</div>
</div>
</section>
This is the console.log output for the list:
{
"type": "group-list-item",
"node": {
"type": "group-list-item",
"items": [
{
"type": "list-item",
"text": "Health",
"spans": [
{
"start": 0,
"end": 6,
"type": "hyperlink",
"data": {
"link_type": "Web",
"url": "https://wellwardmed.com/services/health.html",
"target": "_blank"
}
},
{
"start": 0,
"end": 6,
"type": "strong"
}
],
"direction": "ltr"
},
{
"type": "list-item",
"text": "Energy",
"spans": [
{
"start": 0,
"end": 6,
"type": "hyperlink",
"data": {
"link_type": "Web",
"url": "https://wellwardmed.com/services/energy.html",
"target": "_blank"
}
},
{
"start": 0,
"end": 6,
"type": "strong"
}
],
"direction": "ltr"
},
{
"type": "list-item",
"text": "Activity",
"spans": [
{
"start": 0,
"end": 8,
"type": "hyperlink",
"data": {
"link_type": "Web",
"url": "https://wellwardmed.com/services/activity.html",
"target": "_blank"
}
},
{
"start": 0,
"end": 8,
"type": "strong"
}
],
"direction": "ltr"
},
{
"type": "list-item",
"text": "Lifestyle",
"spans": [
{
"start": 0,
"end": 9,
"type": "hyperlink",
"data": {
"link_type": "Web",
"url": "https://wellwardmed.com/services/lifestyle.html",
"target": "_blank"
}
},
{
"start": 0,
"end": 9,
"type": "strong"
}
],
"direction": "ltr"
}
]
},
"children": [],
"key": "86"
}