Tags

external
Vue.js
Rich text

Astro rich text renderer

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

Advanced: Document Linking

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:

src/components/DocumentLink.astro
---
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 />
src/components/Asset.astro
---
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.

Tags

external
Vue.js
Rich text