@contentful/rich-text-react-renderer
    TypeScript icon, indicating that this package has built-in type declarations

    15.4.0 • Public • Published

    rich-text-react-renderer

    React renderer for the Contentful rich text field type.

    Installation

    Using npm:

    npm install @contentful/rich-text-react-renderer

    Using yarn:

    yarn add @contentful/rich-text-react-renderer

    Usage

    import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
    
    const document = {
      nodeType: 'document',
      data: {},
      content: [
        {
          nodeType: 'paragraph',
          data: {},
          content: [
            {
              nodeType: 'text',
              value: 'Hello world!',
              marks: [],
              data: {}
            },
          ],
        },
      ],
    };
    
    documentToReactComponents(document); // -> <p>Hello world!</p>
    import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
    
    const document = {
      nodeType: 'document',
      content: [
        {
          nodeType: 'paragraph',
          content: [
            {
              nodeType: 'text',
              value: 'Hello',
              marks: [{ type: 'bold' }],
            },
            {
              nodeType: 'text',
              value: ' world!',
              marks: [{ type: 'italic' }],
            },
          ],
        },
      ],
    };
    
    documentToReactComponents(document);
    // -> <p><b>Hello</b><u> world!</u></p>

    You can also pass custom renderers for both marks and nodes as an optional parameter like so:

    import { BLOCKS, MARKS } from '@contentful/rich-text-types';
    import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
    
    const document = {
      nodeType: 'document',
      content: [
        {
          nodeType: 'paragraph',
          content: [
            {
              nodeType: 'text',
              value: 'Hello',
              marks: [{ type: 'bold' }],
            },
            {
              nodeType: 'text',
              value: ' world!',
              marks: [{ type: 'italic' }],
            },
          ],
        },
      ],
    };
    
    const Bold = ({ children }) => <p className="bold">{children}</p>;
    
    const Text = ({ children }) => <p className="align-center">{children}</p>;
    
    const options = {
      renderMark: {
        [MARKS.BOLD]: text => <Bold>{text}</Bold>,
      },
      renderNode: {
        [BLOCKS.PARAGRAPH]: (node, children) => <Text>{children}</Text>,
      },
      renderText: text => text.replace('!', '?'),
    };
    
    documentToReactComponents(document, options);
    // -> <p class="align-center"><p class="bold">Hello</p><u> world?</u></p>

    Last, but not least, you can pass a custom rendering component for an embedded entry:

    import { BLOCKS } from '@contentful/rich-text-types';
    import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
    
    const document = {
      nodeType: 'document',
      content: [
        {
          nodeType: 'embedded-entry-block',
          data: {
            target: (...)Link<'Entry'>(...);
          },
        },
      ]
    };
    
    const CustomComponent = ({ title, description }) => (
      <div>
        <h2>{title}</h2>
        <p>{description}</p>
      </div>
    );
    
    const options = {
      renderNode: {
        [BLOCKS.EMBEDDED_ENTRY]: (node) => {
          const { title, description } = node.data.target.fields;
          return <CustomComponent title={title} description={description} />
        }
      }
    };
    
    documentToReactComponents(document, options);
    // -> <div><h2>[title]</h2><p>[description]</p></div>

    The renderNode keys should be one of the following BLOCKS and INLINES properties as defined in @contentful/rich-text-types:

    • BLOCKS

      • DOCUMENT
      • PARAGRAPH
      • HEADING_1
      • HEADING_2
      • HEADING_3
      • HEADING_4
      • HEADING_5
      • HEADING_6
      • UL_LIST
      • OL_LIST
      • LIST_ITEM
      • QUOTE
      • HR
      • EMBEDDED_ENTRY
      • EMBEDDED_ASSET
    • INLINES

      • EMBEDDED_ENTRY (this is different from the BLOCKS.EMBEDDED_ENTRY)
      • HYPERLINK
      • ENTRY_HYPERLINK
      • ASSET_HYPERLINK

    The renderMark keys should be one of the following MARKS properties as defined in @contentful/rich-text-types:

    • BOLD
    • ITALIC
    • UNDERLINE
    • CODE

    The renderText callback is a function that has a single string argument and returns a React node. Each text node is evaluated individually by this callback. A possible use case for this is to replace instances of \n produced by Shift + Enter with <br/> React elements. This could be accomplished in the following way:

    const options = {
      renderText: text => {
        return text.split('\n').reduce((children, textSegment, index) => {
          return [...children, index > 0 && <br key={index} />, textSegment];
        }, []);
      },
    };

    Note on adding a key prop in custom renderers:

    It is possible to pass a key prop in the components returned by custom renderers. A good use case for this is in embeded entries using the node's target.sys.id. It is important not to pass anything that is index-like (e.g. 1 or "1") as it may clash with the default renderers which automatically inject a key prop using their index in the Contentful rich text AST.

    To work around this limitation, just append any non-numeric character to your custom key.

    const options = {
      renderMark: {
        [MARKS.BOLD]: text => {
          return <b key={`${text}-key`}>{text}</b>;
        },
      },
    };

    Keywords

    none

    Install

    npm i @contentful/rich-text-react-renderer

    DownloadsWeekly Downloads

    192,107

    Version

    15.4.0

    License

    MIT

    Unpacked Size

    208 kB

    Total Files

    75

    Last publish

    Collaborators

    • georgpanok
    • riqwan.thahamir
    • piotr.ciazynski
    • felixboenke
    • amerr
    • khalilful
    • suevalov
    • farruco.sanjurjo
    • johanneswuerbach
    • ronaldronson
    • silhoue
    • phbschmidt
    • timbeyer
    • kathrinholzmann
    • thebesson
    • dominik.markusic
    • eamodeorubio
    • inbal.gordon
    • poberherr
    • kgarbaya
    • kntsay
    • mikita.savanovich
    • laurenceb
    • stupchiy
    • zcei
    • elblivion
    • fabianheymann
    • it-internal
    • guilebarbosa
    • sbezludny
    • medturki
    • danwe
    • m10l
    • cribbles
    • marina-cf
    • dlitvakb
    • malin_sofrone
    • yann-cf
    • makinwa37
    • diacono
    • whydah-gally
    • tauraz
    • cakejelly
    • matthew-hickey
    • martin3walker
    • cstillitano
    • argvk_cf
    • yiotis
    • leonardofreitass
    • hwartig
    • davidfateh
    • gb-ctf-ext
    • dvasylenko
    • ruderngespra
    • arisplakias
    • janikomu
    • mshaaban0
    • vbeleuta
    • freakyfelt
    • taye
    • kdamball
    • burakukula
    • gregferg
    • marcolink
    • gosiaszporer
    • miretxu
    • djagya
    • z0al
    • mspagnolo
    • thomas.spiesser
    • guisantos
    • cezarluiz0
    • kbarnett
    • jwhiles
    • anho
    • erdener
    • sonac
    • didi96
    • fadynaffa3
    • jhbabon
    • fs
    • cgrabo
    • frida.kiriakos
    • dana_grn
    • antesepiccontentful
    • andipaetzold-cf
    • eva.martinez
    • lucabianconi
    • denkristoffer
    • luizfonseca
    • juliabiro
    • vinz93
    • jbourne
    • 0mathcrap
    • damienxy
    • roryscarson
    • m99coder-cf
    • loweisz
    • thomas.contentful
    • marceltoben
    • arnav.luthra
    • anwar.ahmad
    • massao
    • alexdts-cf
    • bohdan.hutsol
    • contentful-ecosystem
    • vida.momenzadeh
    • yuri.mazursky
    • rebecca.koenig
    • annmary