Tags
For Astro, there is a helper library that makes the integration process of rich texts very simple.
To install, use npm or another package manager:
npm install @caisy/rich-text-astro-renderer --save
For ease of use, just pass the JSON and the component will convert it to HTML:
---
import RichTextRenderer from '@caisy/rich-text-astro-renderer';
...
---
<RichTextRenderer node={blogArticle.text.json} />
To ensure that you pass the correct object, it should contain something like this:
{ type: "doc", ... }
An basic example using the rich text render with Astro can also be found here on Stackblitz:
https://stackblitz.com/github/caisy-io/caisy-example-astro
More advanced use case is for example to support linked assets or documents.
Therefor you need to fetch the connections and the json from the graphql API.
So the RichTextRenderer might look like this
<RichTextRenderer
node={post.text.json}
connections={post?.text?.connections}
overwrites={{ documentLink: DocumentLink }}
/>
Where your DocumentLink and Asset component would look like this, to render a linked Asset:
---
import Asset from "./Asset.astro";
const { connections, node } = Astro.props;
---
{
connections &&
connections.map((component) => {
if (
component?.__typename === "Asset" &&
node?.attrs?.documentId === component.id
) {
return (
<Asset {...component} />
);
}
return null;
})
}
<slot />
---
import { Image } from "astro:assets";
const { src, description, width, height } = Astro.props;
---
{
src && (
<Image width={width} height={height} src={src} alt={description} />
)
}
In case you linked an Asset you will always get __typename Asset
- if the user can link other blueprints, you can expert there APIName here as __typename
and check by for them. Remember you can pick the right connection, by matching the id from the connection to the documentId in the rich-text. The example above is using a graphql query partly like this:
text {
json
connections {
__typename
... on Asset {
src
height
width
id
description
}
}
}
For this sample with the images linked you can also find a stackblitz here.
To customize the rendering of code blocks and add syntax highlighting, you can use the overwrites
prop of the RichTextRenderer
component.
Here's an example:
---
import { Code } from "astro:components";
import type { BuiltinLanguage, BundledTheme } from "shiki";
const { node } = Astro.props;
const codeBlockProps = {
theme: "material-theme-palenight" as BundledTheme,
code: node.content[0].text as string,
lang: node.attrs.language as BuiltinLanguage,
wrap: true,
};
---
<Code {...codeBlockProps} />
In this example, we define a CustomCodeBlock
component that receives the code block node as a prop. Inside the component, we extract the relevant properties such as the code content, language, and theme. We then pass these props to Astro's built-in Code
component, which handles the syntax highlighting.
---
import RichTextRenderer from "@caisy/rich-text-astro-renderer";
import CustomCodeBlock from "./CustomCodeBlock.astro";
const { node } = Astro.props;
const overwrites = {
codeBlock: CustomCodeBlock,
};
---
<RichTextRenderer node={node} overwrites={overwrites} />
By providing the overwrites
prop to the RichTextRenderer
, we specify that code blocks should be rendered using our custom CustomCodeBlock
component instead of the default rendering.
This approach allows you to customize the appearance and behavior of code blocks within your rich text content while leveraging Astro's built-in syntax highlighting capabilities.
Tags