Code Monkey home page Code Monkey logo

rich-text's Introduction

Rich Text Helpers

A set of companion packages for Hygraph's Rich Text Field

✨ Packages

⚡️ Examples (Rich Text Renderer)

🤝 Contributing

Thanks for being interested in contributing! We're so glad you want to help! All types of contributions are welcome, such as bug fixes, issues, or feature requests. Also, don't forget to check the roadmap. See CONTRIBUTING.md for ways to get started.

📝 License

Licensed under the MIT License.


Made with 💜 by Hygraph 👋 join our community!

rich-text's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rich-text's Issues

<p> tag className formatting "overwrites" <a> tag ClassName formatting

I have the following code rendering a rich text field in a react app using tailwind:

          <RichText 
            content={post.content.raw}
            renderers={{
              h1: ({ children }) => <h1 className="mx-24 text-3xl font-semibold mb-4">{children}</h1>,
              h2: ({ children }) => <h2 className="mx-24 text-2xl font-semibold mb-4">{children}</h2>,
              h3: ({ children }) => <h3 className="mx-24 text-2xl font-semibold mb-4">{children}</h3>,
              h4: ({ children }) => <h4 className="mx-24 text-2xl font-semibold mb-4">{children}</h4>,
              h5: ({ children }) => <h5 className="mx-24 text-2xl font-semibold mb-4">{children}</h5>,
              bold: ({ children }) => <strong className="mx-24 text-2xl font-semibold mb-4">{children}</strong>,
              link: ({ children, href, rel, title, openInNewTab, id }) => <a className="text-xl text-blue-500 hover-underline">{children}</a>,
              p: ({ children }) => <p className="mx-24 mb-4 text-xl text-left leading-9">{children}</p>,
              code_block: ({ children }) => <code className="mx-24 mb-8 text-sm sm:text-sm inline-flex text-left items-center space-x-4 bg-gray-700 text-gray-200 rounded-md p-8">{children}</code>,
              ul: ({ children }) => <ul className="mx-24 mb-8 text-xl text-left leading-9">{children}</ul>,
              ol: ({ children }) => <ol className="mx-24 text-xl text-left leading-9">{children}</ol>,
              li: ({ children }) => <li className="mx-24 text-xl text-left leading-9">{children}</li>,
              img: ({ children, src, title, height, width }) => <img>{children}</img>,
              table: ({ children }) => <table className="mx-24 mb-1">{children}</table>,
              table_head: ({ children }) => <th className="mx-24 mb-1">{children}</th>,
              table_row: ({ children }) => <tr className="mx-24 mb-1">{children}</tr>,
            }} />

I can't change the format of text within <a> html tags as they always depend on the <p> tag. Tried do delete all formatting, change div (to exclude a potential parent child dependency). I can't find a way to format links differently than body. I also checked the css code but there's no reference to <a> tags.

Screenshot provides example within <RichText /> and right outside of it
Screen Shot 2023-07-08 at 5 43 55 PM

Thank you for any advice you could give me!

RichText renders empty elements resulting in broken design

I've been testing out the <RichText /> and came accross a possible problem which is mainly caused by users providing empty elements in the CMS, but it can cause problems in the design when working with ::after or ::before css selectors or other properties that define the size/appearance of the components.

I have already figured out a solution for this problem, which would be to check whether the element is a media element which can be achieved by checking for a url or src attribute and filtering the children in the element creation process to sort out all text elements containing an empty string.

If you want me to create a pull request for this, I have already written some code to fix this.

PS: A problem could be an empty table cell which needs to be displayed. Because of this, this feature maybe sould be optional.

Accessing image properties from renderer isn't working.

I am having an issue with getting image props from the renderer from the documentation.

Reference

Example:

import { NodeRendererType, astToHtmlString } from '@graphcms/rich-text-html-renderer';

renderers: NodeRendererType = {
   img: ({ src }: Partial<any>) => `<img class="my-6 h-[400px] w-full object-left-top object-cover src="${src}" />`,
};

async addContent(post: { content: { raw: { children: any; }; }; }) {
    const content = post.content.raw.children;
    const rendered = await astToHtmlString({ content: content, renderers: this.renderers });

    return { ...post, rendered }
}

It isn't outputting the src link, it's just blank. but the documentation says I can pass that.

  • img
src: string;
title: string;
width: number;
height: number;
mimeType: ImageMimeTypes;
altText: string;

Import element fuctions to reuse on my own code

Hey, I'm usign @graphcms/rich-text-html-renderer and found a situation where I would like to reuse element functions to use directly on my code inside of custom renderers, currently it only export astToHtmlString function.

My use case:

import { astToHtmlString, Link } from '@graphcms/rich-text-html-renderer'

...
renderers: {
  a: (props) => {
    const condition = true
    return condition
      ? `<a data-condition="special-data">${props.children}</a>`
      : Link(props)
  }
}

With that I could import Link function and keep consistency with rich-text-html-renderer library without rewriting this function as a workaround.

Is today able to import thoses functions in another way or would be able to export together further?

PS: If it's okay to export those functions I could open a PR for that

[help wanted] How to zoom an image rendered by rich-text-renderer with react-awesome-lightbox library

Hello, would you please help me how to zoom an image rendered from rich text? I use this library:
https://github.com/theanam/react-awesome-lightbox#setting-up

// (...)
import Lightbox from "react-awesome-lightbox";
import "react-awesome-lightbox/build/style.css";

// (...)
  <RichText
          content={portfolioItem.content.raw.children}
          renderers={{
            img: ({ src, altText, height, width }) => (
              <Flex alignItems="center" justifyContent="center" pt={4} pb={4}>
                <Image
                  src={src}
                  alt={altText}
                  height={{ base: "full", lg: "920" }}
                  width={{ base: "full", lg: "1920" }}
                  objectFit="cover"
                  border="1px"
                  borderColor={imageBorderColor}
                  onClick={() => {
                    <Lightbox image={src} title="Image Title" />; // zoom on click each image rendered by rich-text-renderer
                  }}
                />
              </Flex>
            ),
          }}
        />

// (...)

[help wanted] Rendering content from graphCMS - Next.js

Hello, would you please help me how to render a content from graphCMS?
I render it like this <RichText content={portfolioItem.content.raw.children} /> but the styles are not applied like in Preview mode in graphCMS rich text field.

[slug].js

import { getPortfolioItem } from "../../lib/data";
import Layout from "../../components/Layout";
import { RichText } from "@graphcms/rich-text-react-renderer";
import { Box, Text } from "@chakra-ui/react";

export const getServerSideProps = async ({ params }) => {
  const portfolioItem = await getPortfolioItem(params.slug);
  return {
    props: {
      portfolioItem: portfolioItem.portfolios[0],
    },
  };
};


const Portfolio = ({ portfolioItem }) => {
  console.log(portfolioItem);
  return (
    <Layout>
      <Box>
        <Text fontSize={{ base: "3xl", md: "5xl" }}>
          {" "}
          {portfolioItem.title}
        </Text>
         <RichText content={portfolioItem.content.raw.children} />
      </Box>
    </Layout>
  );
};

export default Portfolio;

API playground

image

it doesn't render the rich text properly like in preview mode in graphCMS rich text editor - it doesn't bold the text, resize the images etc.

production:
image

graphCMS rich text preview:
image

ClientError: expected RichText raw value to be object:

When transforming my html to ast, when I upsert my data to Hygraph, I get the error:

"ClientError: expected RichText raw value to be object"

The ast object I get back is:

[
  { type: 'paragraph', children: [ [Object] ] },
  { type: 'paragraph', children: [ [Object], [Object] ] },
  {
    type: 'paragraph',
    children: [ [Object], [Object], [Object], [Object], [Object] ]
  },
  { type: 'paragraph', children: [ [Object], [Object] ] },
  { type: 'paragraph', children: [ [Object], [Object] ] },
  {
    type: 'paragraph',
    children: [ [Object], [Object], [Object], [Object] ]
  },
  { type: 'paragraph', children: [ [Object], [Object] ] },
  { type: 'paragraph', children: [ [Object] ] },
  { type: 'paragraph', children: [ [Object] ] },
  { type: 'paragraph', children: [ [Object], [Object] ] },
  {
    type: 'paragraph',
    children: [ [Object], [Object], [Object], [Object] ]
  },
  { type: 'paragraph', children: [ [Object] ] }
]

This is my code. I use text_html: ${{ children: data.text_html }} to insert the ast object.

const { GraphQLClient, gql } = require('graphql-request') // Importing graphql-request library and gql tag
require('dotenv').config() // Importing environment variables from .env file via the dotenv NPM package
const { htmlToSlateAST } = require('@graphcms/html-to-slate-ast')

// Initialize GraphQL client with endpoint and authorization headers
const client = new GraphQLClient(process.env.HYGRAPH_ENDPOINT, {
	headers: {
		authorization: `Bearer ${process.env.HYGRAPH_TOKEN}`,
	},
})

// Function to create a GraphQL mutation based on provided data
// https://hygraph.com/docs/api-reference/content-api/mutations#upsert-entries
function createMutation(data) {
	console.log('data.text_html')
	console.log(data.text_html)
	// console.log('data', data)
	// Create the mutation
	// multiline string: https://stackoverflow.com/questions/45955084/passing-multi-line-string-in-a-graphql-mutation
	const mutation = gql`mutation MyMutation {
    upsertAnnouncement(
        where: { hylexid: "${data._id}" }
        upsert: {
            create: { 
                hylexid: "${data._id}"
                title: "${data.title.trim()}"
                service: "${data.service.trim()}"
                text_html: ${{ children: data.text_html }}
                image: """${JSON.stringify(data.image, null, 2)}"""
                slug: "${data._slug.trim()}"
                date: "${data.date}"
            }
            update: {
                title: "${data.title.trim()}"
                service: "${data.service.trim()}"
                text_html: ${{ children: data.text_html }}
                image: """${JSON.stringify(data.image, null, 2)}"""
                slug: "${data._slug.trim()}"
                date: "${data.date}"
            }
        }
      ) {
        id
    }
  }`
	return mutation
}

const pages = 2
// one page has 15 entries! so 5 * 15 = 75
const intervalTime = 10000
// what do i need this for?
let idsToUpdate = []
let interval
// Asynchronous function to run the migration process
async function run() {
	let i = 0

	// immediately fetch
	console.log(`Running page ${i} of ${pages}`)
	fetchData(i)
	i++

	if (i < pages) {
		// then fetch every 10 seconds
		interval = setInterval(() => {
			if (i > pages) {
				clearInterval(interval)
			}
			console.log(`Running page ${i} of ${pages}`)
			fetchData(i)
			i++
		}, intervalTime)
	}
}

async function toSlate(htmlString) {
	const ast = await htmlToSlateAST(htmlString)
	return ast
}

var fetchData = async function (i) {
	let CAT_API_URL = `https://api.xxxxxx.com/v2/announcements?from=${i}&key=${process.env.EFLUX_API_KEY}`

	let { data } = await fetch(CAT_API_URL).then((res) => res.json())

	const mutations = data.map(async (item, index) => {
		const ast = await toSlate(item.text_html)
		// console.log('ast')
		// console.log(ast)
		item.text_html = ast
		// console.log('item.text_html', item.text_html)
		return createMutation(item)
	})

	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
	Promise.all(mutations).then((mutations) => {
		// console.log('mutations')
		// console.log(mutations)

		// Execute each mutation after a timed delay
		mutations.forEach((item, index) => {
			setTimeout(() => {
				console.log(`Importing announcement ${index + 1} of ${mutations.length} of page ${i} of ${pages + 1}`)
				// Make a request to the GraphQL endpoint using the generated mutation
				client.request(item).then((response) => {
					// console.log(response)
					// console.log('ITEM:')
					// console.log(JSON.stringify(item))
					// console.log('RESPONSE:')
					idsToUpdate.push(response.id)
				}) // Store the retrieved ID for update
			}, (index + 1) * 1000) // Delay each iteration by (index + 1) seconds
		})
	})

}

// Running the migration process
run()

This is the whole error:


ClientError: expected RichText raw value to be object: {"response":{"errors":[{"message":"expected RichText raw value to be object"}],"data":null,"extensions":{"requestId":"clrzz9gimewxb0bldfpixb6ki"},"status":400,"headers":{}},"request":{"query":"mutation MyMutation {\n    upsertAnnouncement(\n        where: { hylexid: \"581215\" }\n        upsert: {\n            create: { \n                hylexid: \"581215\"\n                title: \"Word Script Sign—The Alphabet of Art\"\n                service: \"eflux\"\n                text_html: [object Object]\n                image: \"\"\"{\n  \"thumb\": {\n    \"src\": \"https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg,400x400,c\",\n    \"width\": 400,\n    \"height\": 400\n  },\n  \"medium\": {\n    \"src\": \"https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg,680\",\n    \"width\": 680,\n    \"height\": 906\n  },\n  \"large\": {\n    \"src\": \"https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg,1024\",\n    \"width\": 1024,\n    \"height\": 1365\n  },\n  \"original\": {\n    \"src\": \"https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg?original\",\n    \"width\": 3456,\n    \"height\": 4608\n  }\n}\"\"\"\n                slug: \"word-script-sign-the-alphabet-of-art\"\n                date: \"2024-01-30\"\n            }\n            update: {\n                title: \"Word Script Sign—The Alphabet of Art\"\n                service: \"eflux\"\n                text_html: [object Object]\n                image: \"\"\"{\n  \"thumb\": {\n    \"src\": \"https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg,400x400,c\",\n    \"width\": 400,\n    \"height\": 400\n  },\n  \"medium\": {\n    \"src\": \"https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg,680\",\n    \"width\": 680,\n    \"height\": 906\n  },\n  \"large\": {\n    \"src\": \"https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg,1024\",\n    \"width\": 1024,\n    \"height\": 1365\n  },\n  \"original\": {\n    \"src\": \"https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg?original\",\n    \"width\": 3456,\n    \"height\": 4608\n  }\n}\"\"\"\n                slug: \"word-script-sign-the-alphabet-of-art\"\n                date: \"2024-01-30\"\n            }\n        }\n      ) {\n        id\n    }\n  }"}}
    at makeRequest (/Users/arminunruh/Documents/git/eflux-hygraph-migration/node_modules/graphql-request/build/cjs/index.js:310:15)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  response: {
    errors: [ { message: 'expected RichText raw value to be object' } ],
    data: null,
    extensions: { requestId: 'clrzz9gimewxb0bldfpixb6ki' },
    status: 400,
    headers: Headers {
      [Symbol(map)]: [Object: null prototype] {
        date: [ 'Tue, 30 Jan 2024 06:28:33 GMT' ],
        'content-type': [ 'application/json' ],
        'content-length': [ '134' ],
        connection: [ 'keep-alive' ],
        'cf-ray': [ '84d7a7ca7e37727c-HAM' ],
        'cf-cache-status': [ 'DYNAMIC' ],
        'cache-control': [ 'private, no-store' ],
        vary: [ 'Origin, Accept-Encoding' ],
        'x-cdn-cache-status': [
          'optimize,skip-no-query-op,disable-cdn-not-cacheable,disable-cdn,no-transform-is-mutation,fetch-origin,reject-not-ok,update-project'
        ],
        'x-request-id': [ 'clrzz9gimewxb0bldfpixb6ki' ],
        'report-to': [
          '{"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=zvTpVM0sOeWEqBHNoy8fJSTbyvhyDhqftWa%2BvJ6lALJNWKeC%2BelelG34c6sX5fLvF6wqdQmtzhE%2FJP2c0t7rykvTmLHuoDSt9CIIrYsZGTj7PI2qUfxbzl8W9FLg439VTwmW2I7Xp0xwEfyRHHWtj7YHlsscoJW8b1saGTg0uuw090F3J8hB"}],"group":"cf-nel","max_age":604800}'
        ],
        nel: [
          '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}'
        ],
        server: [ 'cloudflare' ]
      }
    }
  },
  request: {
    query: 'mutation MyMutation {\n' +
      '    upsertAnnouncement(\n' +
      '        where: { hylexid: "581215" }\n' +
      '        upsert: {\n' +
      '            create: { \n' +
      '                hylexid: "581215"\n' +
      '                title: "Word Script Sign—The Alphabet of Art"\n' +
      '                service: "eflux"\n' +
      '                text_html: [object Object]\n' +
      '                image: """{\n' +
      '  "thumb": {\n' +
      '    "src": "https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg,400x400,c",\n' +
      '    "width": 400,\n' +
      '    "height": 400\n' +
      '  },\n' +
      '  "medium": {\n' +
      '    "src": "https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg,680",\n' +
      '    "width": 680,\n' +
      '    "height": 906\n' +
      '  },\n' +
      '  "large": {\n' +
      '    "src": "https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg,1024",\n' +
      '    "width": 1024,\n' +
      '    "height": 1365\n' +
      '  },\n' +
      '  "original": {\n' +
      '    "src": "https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg?original",\n' +
      '    "width": 3456,\n' +
      '    "height": 4608\n' +
      '  }\n' +
      '}"""\n' +
      '                slug: "word-script-sign-the-alphabet-of-art"\n' +
      '                date: "2024-01-30"\n' +
      '            }\n' +
      '            update: {\n' +
      '                title: "Word Script Sign—The Alphabet of Art"\n' +
      '                service: "eflux"\n' +
      '                text_html: [object Object]\n' +
      '                image: """{\n' +
      '  "thumb": {\n' +
      '    "src": "https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg,400x400,c",\n' +
      '    "width": 400,\n' +
      '    "height": 400\n' +
      '  },\n' +
      '  "medium": {\n' +
      '    "src": "https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg,680",\n' +
      '    "width": 680,\n' +
      '    "height": 906\n' +
      '  },\n' +
      '  "large": {\n' +
      '    "src": "https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg,1024",\n' +
      '    "width": 1024,\n' +
      '    "height": 1365\n' +
      '  },\n' +
      '  "original": {\n' +
      '    "src": "https://images.e-flux-systems.com/581215_0e60b22986a89d2e23433b61e8d1a6bc.jpg?original",\n' +
      '    "width": 3456,\n' +
      '    "height": 4608\n' +
      '  }\n' +
      '}"""\n' +
      '                slug: "word-script-sign-the-alphabet-of-art"\n' +
      '                date: "2024-01-30"\n' +
      '            }\n' +
      '        }\n' +
      '      ) {\n' +
      '        id\n' +
      '    }\n' +
      '  }',
    variables: undefined
  }
}

my package json:

{
	"name": "xxx-hygraph-migration",
	"version": "1.0.0",
	"description": "",
	"main": "migration.js",
	"scripts": {
		"test": "echo \"Error: no test specified\" && exit 1"
	},
	"keywords": [],
	"author": "",
	"license": "ISC",
	"dependencies": {
		"@graphcms/html-to-slate-ast": "^0.13.3",
		"dotenv": "^16.4.1",
		"graphql-request": "^6.1.0",
		"html-entities": "^2.4.0",
		"jsdom": "^24.0.0",
		"slate": "^0.66.1",
		"slate-hyperscript": "^0.67.0"
	}
}

Is there any way to render rich text in vue effectively?

Hello, I've started to play around with GraphCMS and it's so far so good.

We use Vue in the team and have a lot of references in the rich text contents we created and I cannot come up with any ideas to renderer them with the raw value.

Coud you recommend me the way to render them without rewriting the package for vue (if there is any)

Thank you

Rendering rich text content

Hello, would you please help me how to render a content from graphCMS?
I render it like this <RichText content={portfolioItem.content.raw.children} /> but the styles are not applied like in Preview mode in graphCMS rich text field.

[slug].js

import { getPortfolioItem } from "../../lib/data";
import Layout from "../../components/Layout";
import { RichText } from "@graphcms/rich-text-react-renderer";
import { Box, Text } from "@chakra-ui/react";

export const getServerSideProps = async ({ params }) => {
  const portfolioItem = await getPortfolioItem(params.slug);
  return {
    props: {
      portfolioItem: portfolioItem.portfolios[0],
    },
  };
};


const Portfolio = ({ portfolioItem }) => {
  console.log(portfolioItem);
  return (
    <Layout>
      <Box>
        <Text fontSize={{ base: "3xl", md: "5xl" }}>
          {" "}
          {portfolioItem.title}
        </Text>
         <RichText content={portfolioItem.content.raw.children} />
      </Box>
    </Layout>
  );
};

export default Portfolio;

API playground

image

it doesn't render the rich text properly like in preview mode in graphCMS rich text editor - it doesn't bold the text, resize the images etc.

production:
image

graphCMS rich text preview:
image

I have to reassign every markdown: eg. h1,h2, p tags, img etc? Why it doesn't look like in rich text editor preview mode "out of box"? Got to do something with renderers={{ h1: ({ children }) => (// some styles) }} and so on? with h2, h3, p tags?

 <RichText
          content={portfolioItem.content.raw.children}
          renderers={{
            h1: ({ children }) => (
              <Heading as="h1" color={colorH1} align="left">
                {children}
              </Heading>
            ),
            h2: ({ children }) => (
              <Text
                color={colorH2}
                align="left"
                fontSize="3xl"
                fontWeight="700"
              >
                {children}
              </Text>
            ),
            h3: ({ children }) => (
              <Text color={colorH3} align="left" fontSize="xl" fontWeight="600">
                {children}
              </Text>
            ),
            p: ({ children }) => (
              <Text fontSize="lg" fontWeight="400">
                {children}
              </Text>
            ),
            bold: ({ children }) => <strong>{children}</strong>,
            img: ({ src, altText, height, width }) => (
              <Flex alignItems="center" justifyContent="center" pt={4} pb={4}>
                <Image
                  src={src}
                  alt={altText}
                  height={{ base: "full", lg: "980" }}
                  width={{ base: "full", lg: "1920" }}
                  objectFit="cover"
                  border="1px"
                  borderColor={imageBorderColor}
              
                />
              </Flex>
            ),
          }}
        />

Video Props typings are not correct

The Video Node Renderer has the following types:
type VideoNodeRenderer = (props: Partial<VideoProps>) => JSX.Element;

VideoProps is as follows:

export interface VideoProps {
    src: string;
    title?: string;
    width?: number;
    height?: number;
    handle?: string;
}

However the RichText response is

...
          src: 'https://media.graphassets.com/CGcmuQqOSDKd88lYEApe',
          type: 'video',
          title: 'lifetime-membership.mp4',
          width: null,
          handle: 'CGcmuQqOSDKd88lYEApe',
          height: null,
          children: [{ text: '' }],
          mimeType: 'video/mp4',
...

I can't without fudging the types on my end access the mimeType or "type" properties. Also the width and height are not types correctly. They probably should be Maybe<number>

I am happy to raise a pull request to fix if needed? I assume we should look at more of the responses too like Image and Audio?

Impossible to render a clickable image with Reactjs and rich-text

Hey there!
First of all sorry about my English, it's not my first langage :)

What I want

I'm trying to make images automaticaly clickable in my React js app.

The issue :

No matter how I code it, it doesn't work. I tried with a lightroom library, a modal from react-modal-image, nothing works.
My last attempt was with a simple link but it doesn't work either.

My last try

Component code

function PostCard({ posts }) { const unipopiaPosts = posts.filter((post) => post.node.categories.some((category) => category.nom === 'Unipopia'));

return (
<article className="post__block"> {unipopiaPosts.map((unipopia) => ( <div key={unipopia.node.slug}> <div className="post__title"> {unipopia.node.titre} </div> <div className="post__excerpt"> {unipopia.node.extrait} </div> <div className="post__content"> <RichText content={unipopia.node.contenu.raw} renderers={{ image: ({ node }) => { const imageUrl = node.children[0].src; return ( <a href={imageUrl} target="_blank" rel="noopener noreferrer"> <img alt={node.children[0].title} src={imageUrl} height={node.children[0].height} width={node.children[0].width} /> </a> ); }, }} /> </div> </div> ))} </article>
); }

Could you help me please?

RichText rendering nested li's causing nextjs hydration errors

Hi, our team relies pretty heavly on both hygraph and this packages and after recent migration to react 18 which is more strict on the valid node nesting it turned out that RichText component is rendering list elements as nested li tags which cause hydration issues in next.

Here's an minimal example using data copied straight from our hygraph:
https://github.com/MaciejWiatr/rich-text-react-renderer-li-issue/blob/main/src/pages/index.tsx
https://rich-text-react-renderer-li-issue.vercel.app/

Screenshots:
image
image
image
Full error messages:

Warning: Expected server HTML to contain a matching 
  • in
  • . li li@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:190:20 RenderElement@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:389:17 RenderNode@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:354:14 RenderElements@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:507:17 list_item_child@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:274:20 RenderElement@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:389:17 RenderNode@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:354:14 RenderElements@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:507:17 li li@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:190:20 RenderElement@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:389:17 RenderNode@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:354:14 RenderElements@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:507:17 ul ul@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:182:20 RenderElement@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:389:17 RenderNode@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:354:14 RenderElements@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:507:17 RichText@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:524:17 div Home App@webpack-internal:///./src/pages/_app.tsx:9:38 PathnameContextProviderAdapter@webpack-internal:///./node_modules/next/dist/shared/lib/router/adapters.js:62:34 ErrorBoundary@webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:301:63 ReactDevOverlay@webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:850:908 Container@webpack-internal:///./node_modules/next/dist/client/index.js:61:1 AppContainer@webpack-internal:///./node_modules/next/dist/client/index.js:171:25 Root@webpack-internal:///./node_modules/next/dist/client/index.js:346:37 [next-dev.js:20:25](webpack://_N_E/node_modules/next/dist/client/next-dev.js?3515) Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.

    See more info here: https://nextjs.org/docs/messages/react-hydration-error
    React 12
    workLoop scheduler.development.js:266
    flushWork scheduler.development.js:239
    performWorkUntilDeadline scheduler.development.js:533
    EventHandlerNonNull* scheduler.development.js:571
    scheduler.development.js:633
    NextJS 4
    index.js:6
    NextJS 4
    React 2
    NextJS 4
    React
    NextJS 4
    React
    NextJS 4
    index.js:14
    NextJS 4
    next-dev.js:3
    NextJS 7
    react-dom.development.js:12507
    Warning: An error occurred during hydration. The server HTML was replaced with client content in

    .

    See more info here: https://nextjs.org/docs/messages/react-hydration-error next-dev.js:20:25
    Warning: validateDOMNesting(...):

  • cannot appear as a descendant of
  • .
    li
    li@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:190:20
    RenderElement@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:389:17
    RenderNode@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:354:14
    RenderElements@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:507:17
    list_item_child@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:274:20
    RenderElement@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:389:17
    RenderNode@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:354:14
    RenderElements@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:507:17
    li
    li@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:190:20
    RenderElement@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:389:17
    RenderNode@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:354:14
    RenderElements@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:507:17
    ul
    ul@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:182:20
    RenderElement@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:389:17
    RenderNode@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:354:14
    RenderElements@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:507:17
    RichText@webpack-internal:///./node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:524:17
    div
    Home
    App@webpack-internal:///./src/pages/_app.tsx:9:38
    PathnameContextProviderAdapter@webpack-internal:///./node_modules/next/dist/shared/lib/router/adapters.js:62:34
    ErrorBoundary@webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:301:63
    ReactDevOverlay@webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:850:908
    Container@webpack-internal:///./node_modules/next/dist/client/index.js:61:1
    AppContainer@webpack-internal:///./node_modules/next/dist/client/index.js:171:25
    Root@webpack-internal:///./node_modules/next/dist/client/index.js:346:37 next-dev.js:20:25
    Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.

    See more info here: https://nextjs.org/docs/messages/react-hydration-error
    React 9
    workLoop scheduler.development.js:266
    flushWork scheduler.development.js:239
    performWorkUntilDeadline scheduler.development.js:533
    EventHandlerNonNull* scheduler.development.js:571
    scheduler.development.js:633
    NextJS 4
    index.js:6
    NextJS 4
    React 2
    NextJS 4
    React
    NextJS 4
    React
    NextJS 4
    index.js:14
    NextJS 4
    next-dev.js:3
    NextJS 7
    7 react-dom.development.js:12507
    Uncaught Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
    React 8
    workLoop scheduler.development.js:266
    flushWork scheduler.development.js:239
    performWorkUntilDeadline scheduler.development.js:533
    EventHandlerNonNull* scheduler.development.js:571
    scheduler.development.js:633
    NextJS 4
    index.js:6
    NextJS 4
    React 2
    NextJS 4
    React
    NextJS 4
    React
    NextJS 4
    index.js:14
    NextJS 4
    next-dev.js:3
    NextJS 7

  • React duplicate key issue

    Running this sandbox with some sample data from GraphCMS flags the following error:

    Warning: Encountered two children with the same key, ``. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
        at RenderText (https://i91ddf.csb.app/node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:316:23)
        at RenderNode (https://i91ddf.csb.app/node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:359:19)
        at RenderElements (https://i91ddf.csb.app/node_modules/@graphcms/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:445:23)
    

    It looks like this is caused by a '\n' being included in the text content which may be causing additional nodes to be generated that aren't being tracked correctly

    Newline added by astToHtmlString for link object

    Hello,

    astToHtmlString method adds a newline (\n) and whitespaces around a link object.

    Input richtext object:

    {
      "children": [
        {
          "type": "paragraph",
          "children": [
            {
              "text": "Lorem ipsum dolor sit amet, "
            },
            {
              "type": "link",
              "href": "https://google.com",
              "children": [
                {
                  "text": "consectetur "
                }
              ]
            },
            {
              "text": "adipiscing elit, sed do ..."
            }
          ]
        }
      ]
    }
    

    Output:
    <p>Lorem ipsum dolor sit amet, \n <a href="https://google.com" target="_self" >\n consectetur \n </a>\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua</p>

    Error: Cannot find module './xhr-sync-worker.js'

    node:internal/modules/cjs/loader:1048
      const err = new Error(message);
                  ^
    
    Error: Cannot find module './xhr-sync-worker.js'
    Require stack:
    - /Users/arminunruh/Documents/git/eflux-hygraph-migration/node_modules/@graphcms/html-to-slate-ast/dist/chunk-ARIXHL5V.js
    - /Users/arminunruh/Documents/git/eflux-hygraph-migration/node_modules/@graphcms/html-to-slate-ast/dist/index.js
    - /Users/arminunruh/Documents/git/eflux-hygraph-migration/migration.js
        at Module._resolveFilename (node:internal/modules/cjs/loader:1048:15)
        at Function.resolve (node:internal/modules/helpers:136:19)
        at /Users/arminunruh/Documents/git/eflux-hygraph-migration/node_modules/@graphcms/html-to-slate-ast/dist/api-VUY5N4BO.js:869:12366
        at /Users/arminunruh/Documents/git/eflux-hygraph-migration/node_modules/@graphcms/html-to-slate-ast/dist/chunk-ARIXHL5V.js:3:443
        at /Users/arminunruh/Documents/git/eflux-hygraph-migration/node_modules/@graphcms/html-to-slate-ast/dist/api-VUY5N4BO.js:870:20714
        at /Users/arminunruh/Documents/git/eflux-hygraph-migration/node_modules/@graphcms/html-to-slate-ast/dist/chunk-ARIXHL5V.js:3:443
        at /Users/arminunruh/Documents/git/eflux-hygraph-migration/node_modules/@graphcms/html-to-slate-ast/dist/api-VUY5N4BO.js:876:73493
        at /Users/arminunruh/Documents/git/eflux-hygraph-migration/node_modules/@graphcms/html-to-slate-ast/dist/chunk-ARIXHL5V.js:3:443
        at /Users/arminunruh/Documents/git/eflux-hygraph-migration/node_modules/@graphcms/html-to-slate-ast/dist/api-VUY5N4BO.js:876:81936
        at /Users/arminunruh/Documents/git/eflux-hygraph-migration/node_modules/@graphcms/html-to-slate-ast/dist/chunk-ARIXHL5V.js:3:443 {
      code: 'MODULE_NOT_FOUND',
      requireStack: [
        '/Users/arminunruh/Documents/git/eflux-hygraph-migration/node_modules/@graphcms/html-to-slate-ast/dist/chunk-ARIXHL5V.js',
        '/Users/arminunruh/Documents/git/eflux-hygraph-migration/node_modules/@graphcms/html-to-slate-ast/dist/index.js',
        '/Users/arminunruh/Documents/git/eflux-hygraph-migration/migration.js'
      ]
    }
    
    Node.js v20.9.0
    

    This is my code below. Just getting the HTML which is in data.text_html works.
    The whole migration works fine, only when i use htmlToSlateAST it gives me this error above.

    // TODO: https://github.com/hygraph/rich-text/tree/main/packages/html-to-slate-ast
    // https://hygraph.com/docs/getting-started/fundamentals/migrating-to-hygraph#content-api
    
    // Import necessary libraries
    const { GraphQLClient, gql } = require('graphql-request') // Importing graphql-request library and gql tag
    require('dotenv').config() // Importing environment variables from .env file via the dotenv NPM package
    
    // Initialize GraphQL client with endpoint and authorization headers
    const client = new GraphQLClient(process.env.HYGRAPH_ENDPOINT, {
    	headers: {
    		authorization: `Bearer ${process.env.HYGRAPH_TOKEN}`,
    	},
    })
    
    const { htmlToSlateAST } = require('@graphcms/html-to-slate-ast')
    
    // Function to create a GraphQL mutation based on provided data
    // https://hygraph.com/docs/api-reference/content-api/mutations#upsert-entries
    async function createMutation(data) {
    	const ast = await htmlToSlateAST(data.text_html)
    	console.log(JSON.stringify(ast, null, 2))
    	// Create the mutation
    	// multiline string: https://stackoverflow.com/questions/45955084/passing-multi-line-string-in-a-graphql-mutation
    	const mutation = gql`mutation MyMutation {
        upsertAnnouncement(
            where: { hylexid: "${data._id}" }
            upsert: {
                create: { 
                    hylexid: "${data._id}"
                    title: "${data.title.trim()}"
                    service: "${data.service.trim()}"
                    text_html: """${data.text_html.trim()}"""
                    image: """${JSON.stringify(data.image, null, 2)}"""
                    slug: "${data._slug.trim()}"
                    date: "${data.date}"
                }
                update: {
                    title: "${data.title.trim()}"
                    service: "${data.service.trim()}"
                    text_html: """${data.text_html.trim()}"""
                    image: """${JSON.stringify(data.image, null, 2)}"""
                    slug: "${data._slug.trim()}"
                    date: "${data.date}"
                }
            }
          ) {
            id
        }
      }`
    	return mutation
    }
    
    const pages = 1
    // what do i need this for?
    let idsToUpdate = []
    
    // Asynchronous function to run the migration process
    async function run() {
    	let i = 0
    
    	let interval = setInterval(() => {
    		if (i > pages) {
    			clearInterval(interval)
    		}
    		console.log(`Running page ${i} of ${pages}`)
    
    		fetchData(i)
    
    		i++
    	}, 10000)
    }
    
    var fetchData = async function (i) {
    	let CAT_API_URL = `https://xxxxxxxxxx/v2/announcements?from=${i}&key=${process.env.API_KEY}`
    
    	const { data } = await fetch(CAT_API_URL).then((res) => res.json())
    
    	// Generate an array of GraphQL mutations based on the retrieved data
    	const mutations = data.map((item, index) => {
    		return createMutation(item)
    	})
    
    	// Execute each mutation after a timed delay
    	mutations.forEach((item, index) => {
    		setTimeout(() => {
    			console.log(`Running mutation ${index + 1} of ${mutations.length}`)
    			// Make a request to the GraphQL endpoint using the generated mutation
    			client.request(item).then((response) => {
    				// console.log('ITEM:')
    				// console.log(item)
    				// console.log('RESPONSE:')
    				// console.log(response)
    				idsToUpdate.push(response.id)
    			}) // Store the retrieved ID for update
    		}, (index + 1) * 1000) // Delay each iteration by (index + 1) seconds
    	})
    }
    
    // Running the migration process
    run()

    Error in elementIsEmpty

    I've got an issue where an empty heading throws an exception.

    [@GraphCMS]/rich-text-react-renderer/dist/rich-text-react-renderer.esm.js:382:5
    WebpackError: TypeError: Cannot read properties of undefined (reading 'text')

    Here's an excerpt from the json

    {"type": "heading-two",
        {
            {
                "children": [
                    {
                        "children": [
                            "text": ""
                        ]
                    }
                ]
            }
        }
    }
    

    I think we need to check that children[0].text actually exists

    Link is not recognized

    Hi,

    I'm trying to use link renderer for this object below, the link is an image pasted in editor.
    image

    The a pick the link up, but not link

    {
        "raw": {
          "children": [
            {
              "type": "paragraph",
              "children": [
                {
                  "text": "This is example of text entry. It has image.\n⁠\n⁠"
                },
                {
                  "href": "blob:https://app.hygraph.com/xx",
                  "type": "link",
                  "title": "(Image)",
                  "children": [
                    {
                      "text": "blob:https://app.hygraph.com/xx"
                    }
                  ],
                  "openInNewTab": true
                },
                {
                  "text": ""
                }
              ]
            }
          ]
        }
    }
    

    Iframe get render as <p>

    When I use an <iframe> in a Rich Text Field, in my queris not recognise as iframe type because it comes wrap in a

    tag.

    ie.

    <p<iframe ...></p>
    

    Any idea why is this happening? Doesn't seems to be any documentation online

    Update @graphcms/html-to-slate-ast to use newer versions of Slate

    @graphcms/html-to-slate-ast lists the following as peer deps:

    # required peer-dependancies
    npm install [email protected] [email protected]
    npm install @graphcms/html-to-slate-ast
    

    Installing [email protected] introduces critical security issues according to npm audit

    Severity: critical
    Prototype Pollution in immer - https://github.com/advisories/GHSA-c36v-fmgq-m8hx
    Prototype Pollution in immer - https://github.com/advisories/GHSA-33f9-j839-rf8h
    fix available via `npm audit fix --force`
    Will install [email protected], which is a breaking change
    node_modules/immer
      slate  0.50.0 - 0.66.0-2021725134429 || >=1.0.0-2021312830
      Depends on vulnerable versions of immer
      node_modules/slate
    

    Add anchor tag support for Page Navigation

    Hi,

    First if all, thanks for this awesome lib. It has simplified my implementation.

    Problem Statement: As a user I want to navigate within the same page using anchor tags.
    Type: Enhancement

    I am using Hygraph rich-text and as of now, I could not find a way to add id to the div. I want to add id to div so that, I am able to navigate within the page using anchor tags.

    Solution: This use case will mostly apply to headings. In Rich text editor I can add a class to heading with prefix anchor- and in the package add an id to div, if classname matches the prefix. Id will be same as classname. (This is not a very good approach, but I can not think of any other solution. )

    Enhance https://github.com/hygraph/rich-text/blob/main/packages/react-renderer/src/elements/Class.tsx

    <p></p> returned in empty rich text box

    When anyone accidentally click into rich text field it automatically create and empty paragraph. The API is then inconsistent.
    In proper empty field the return is NULL and "clicked" field it return "

    "
    This makes front end testing complicated when do not render if the field is empty.

    Solution:
    on hygraph side check if the field is "optically" empty before the safe and remove empty paragraph tags.

    Link embed with Assets not working

    Hello,

    I tried to link an asset (in my example image) with link embed but its getting rendered as an asset / image instead of a link.
    I checked the code and found the following line:

    if (isEmbed && nodeType !== 'Asset') {

    There is a condition on type link if its not an asset. Therefor it is not possible to reference an asset in link embed.

    Is this a bug or how does this work?
    As per documentation it should work to reference assets in links: https://hygraph.com/docs/api-reference/content-api/rich-text-field#embed-assets

    Hope you can help me out :)

    Best regards
    Tobi

    Any workarounds for code block language?

    This is great plugin! I've started messing around with MDX in next.js but didn't really want to use markdown.
    Was thinking how can I render all this nested objects from rich text? And then found this plugin!

    I'm trying to figure out how to highlight code for a specific language? There is a note saying it is not supported.

    Note: we still don't support defining a custom language for a code block in the Rich Text field.

    Is there a way to pass this the lang somehow to Prism?
    I thought maybe class can help, however it changes hierarchy. The object becomes type "class" instead of "code-block".

          {
            "type": "class",
            "children": [
              {
                "type": "code-block",
                "children": [
                  {
                    "text": "// If we execute the following line in the console...' }"
                  }
                ]
              }
            ],
            "className": "language-js"
          }
    

    GraphCMS Marcom website says to use children as prop

    Issue

    Didnt know where else to put it but figured I would try to be a good citizen of the community and put this up somewhere
    For react children as a prop throws an error

    How to reproduce

    1. copy and paste this example from graphcms.com
    const App = () => {
      return (
        <div>
          <RichText
            children={content}
            renderers={{
              h1: ({ children }) => <h1 className="text-white">{children}</h1>,
              bold: ({ children }) => <strong>{children}</strong>,
            }}
          />
        </div>
      );
    };
    
    1. React will get big mad and throw an error
    Failed to compile
    src/views/ACoolComponent.jsx
      Line XX:XX:  Do not pass children as props. Instead, nest children between the opening and closing tags  react/no-children-prop
    
    Search for the keywords to learn more about each error.
    

    URL: https://graphcms.com/blog/graphcms-react-rich-text-renderer
    image

    All rendered elements have the same id

    When I rendered using RichText, the ids were all unified.
    Specifically, all the ids are "[object Object]".

    I would like to create a table of contents, but I can't transition as I would like with this.
    What should I specify for the id?

    Please let me know how to fix this.
    Thank you very much for your help.

    By the way, this is the code.

                <RichText
                  content={bodyContents}
                  renderers={{
                    h1: ({ children }) => (
                      <h1 id={children} className={styles.body__h1}>
                        {children}
                      </h1>
                    ),
                    h2: ({ children }) => (
                      <h2 id={children} className={styles.body__h2}>
                          {children}
                      </h2>
                    ),
    

    Error while rendering Heading 2 with nested link

    Hi, I noticed that RichText component fails to render content when there is Heading 2 (it probably concerns also other elements) with nested link. The error is

    TypeError: Cannot assign to read only property 'children' of object '#<Object>'
    

    GraphCMS content looks like this
    image

    Code that reproduces this this issue below

    import { RichText } from '@graphcms/rich-text-react-renderer'
    
    const Component = () => {
      const raw = {
        children: [
          {
            type: 'heading-two',
            children: [
              {
                text: '',
              },
              {
                href: 'https://google.com',
                type: 'link',
                children: [
                  {
                    text: 'Test heading',
                  },
                ],
              },
              {
                text: '',
              },
            ],
          },
        ],
      }
    
      return <RichText content={raw} />
    }

    Recommend Projects

    • React photo React

      A declarative, efficient, and flexible JavaScript library for building user interfaces.

    • Vue.js photo Vue.js

      🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

    • Typescript photo Typescript

      TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

    • TensorFlow photo TensorFlow

      An Open Source Machine Learning Framework for Everyone

    • Django photo Django

      The Web framework for perfectionists with deadlines.

    • D3 photo D3

      Bring data to life with SVG, Canvas and HTML. 📊📈🎉

    Recommend Topics

    • javascript

      JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

    • web

      Some thing interesting about web. New door for the world.

    • server

      A server is a program made to process requests and deliver data to clients.

    • Machine learning

      Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

    • Game

      Some thing interesting about game, make everyone happy.

    Recommend Org

    • Facebook photo Facebook

      We are working to build community through open source technology. NB: members must have two-factor auth.

    • Microsoft photo Microsoft

      Open source projects and samples from Microsoft.

    • Google photo Google

      Google ❤️ Open Source for everyone.

    • D3 photo D3

      Data-Driven Documents codes.