ADF renderer

This section describes a Forge preview feature. Preview features are deemed stable; however, they remain under active development and may be subject to shorter deprecation windows. Preview features are suitable for early adopters in production environments.

We release preview features so partners and developers can study, test, and integrate them prior to General Availability (GA). For more information, see Forge release phases: EAP, Preview, and GA.

To add the AdfRenderer component to your app:

1 import { AdfRenderer } from '@forge/react';

Description

The AdfRenderer component provides a way to render a valid ADF document, using the same renderer that Atlassian uses internally to render ADF content in Confluence pages, Jira work items, and so on. It allows you to replace node types that are unsupported in the context of a Forge app with replacement content, or remove them entirely. See Atlassian Document Format for information on valid nodes.

This component uses @atlaskit/renderer under the hood.

Visit Renderer editor for a comprehensive list of different ADF document examples

Accessibility considerations

When using the replaceUnsupportedNode prop you will need to ensure that any content is replaced with accessible content. This content needs to be clear to the user it has been replaced. Including an explanation as to why the content is replaced can also be useful. Read more about Readable content (as per WCAG success criterion)

This helps users who use:

  • Screen readers
  • Braille display
  • Text-to-speech technology

Props

NameTypeRequiredDescription
documentDocNodeYesAn ADF document to render
replaceUnsupportedNodeVisitorNoA function to determine behaviour for handling unsupported nodes:
  • Return a new Node to replace the unsupported one
  • Return false to remove the node entirely
  • Return undefined to leave the node as-is (default behaviour)

See @atlaskit/renderer for the full list of props supported by the underlying component.

Unsupported node types

Node typeSupportDetails
mediaPartialOnly supports media hosted by Atlassian when used in a Confluence macro module. You can identify Atlassian hosted `media` nodes as they have an attrs.id property, instead of attrs.url
emojiPartialOnly standard Unicode emoji are supported, not custom user-provided emoji

extension

inlineExtension

bodiedExtension

NoneDoes not support any core Confluence, Connect, or Forge macros

Examples

Basic text rendering

This demonstrates how a simple ADF document is rendered.

Example image of a rendered valid basic ADF document

1
2
import { AdfRenderer } from '@forge/react';

export default () => {
    const simpleDocumentToRender = {
        "type": "doc",
        "version": 1,
        "content": [
            {
                "type": "paragraph",
                "content": [
                    {
                        "type": "text",
                        "text": "This is a simple text example",
                    },
                ],
            },
        ]
    }

    return <AdfRenderer document={simpleDocumentToRender} />
};

Rendering unsupported content

This demonstrates how unsupported content might render by default, without any explicit replacement logic defined.

Example image of a rendered valid ADF document with unsupported content

1
2
import { AdfRenderer } from '@forge/react';

export default () => {
    const simpleDocumentToRender = {
        "type": "doc",
        "version": 1,
        "content": [
            {
                "type": "paragraph",
                "content": [
                    {
                        type: 'emoji',
                        "attrs": {
                            "shortName": ":custom-emoji-hello:",
                            "id": "1e35b00f-cb17-4d28-91a5-ad38700715ae",
                            "text": ":hello!:"
                        }
                    },
                ],
            },
        ]
    }

    return <AdfRenderer document={simpleDocumentToRender} />
};

Replacing unsupported content

This demonstrates a simple replacement function that just replaces unsupported content with a paragraph.

Example image of a rendered valid ADF document with unsupported content replaced

1
2
import { AdfRenderer } from '@forge/react';

export default () => {
    const replaceUnsupportedNode = (node) => {
        return {
            type: 'paragraph',
            content: [{
                type: 'text',
                text: `Unsupported content: ${node.type}`
            }],
        };
    }
    
    const simpleDocumentToRender = {
        "type": "doc",
        "version": 1,
        "content": [
            {
                "type": "paragraph",
                "content": [
                    {
                        type: 'emoji',
                        "attrs": {
                            "shortName": ":custom-emoji-hello:",
                            "id": "1e35b00f-cb17-4d28-91a5-ad38700715ae",
                            "text": ":hello!:"
                        }
                    },
                ],
            },
        ]
    }

    return <AdfRenderer document={simpleDocumentToRender} replaceUnsupportedNode={replaceUnsupportedNode} />
};

Replacing multiple content types

This demonstrates a more complex replacement function that either replaces content, removes it, and or leaves it as-is, depending on the node type.

Example image of a rendered valid ADF document with unsupported content replaced

1
2
import { AdfRenderer } from '@forge/react';

export default () => {
    const replaceUnsupportedNode = (node) => {
        if (node.type.toLowerCase().includes("extension")) {
            // Show a message for all extension node types
            return {
                type: 'paragraph',
                content: [{
                    type: 'text',
                    text: 'Unsupported macro'
                }]
            };
        } else if (node.type === "emoji") {
            // Show the emoji's default textual representation as-is
            return undefined;
        }

        // Hide everything else
        return false;
    }
    
    const simpleDocumentToRender = {
        "type": "doc",
        "version": 1,
        "content": [
            {
                "type": "paragraph",
                "content": [
                    {
                        type: 'emoji',
                        "attrs": {
                            "shortName": ":custom-emoji-hello:",
                            "id": "1e35b00f-cb17-4d28-91a5-ad38700715ae",
                            "text": ":hello!:"
                        }
                    },
                    {
                        "type": "bodiedExtension",
                        "attrs": {
                            "extensionType": "com.atlassian.fabric",
                            "extensionKey": "clock"
                        },
                        "content": [
                            {
                                "type": "paragraph",
                                "content": [
                                    {
                                        "type": "text",
                                        "text": "This is the default content of the extension"
                                    }
                                ]
                            }
                        ]
                    },
                ],
            },
        ]
    }

    return <AdfRenderer document={simpleDocumentToRender} replaceUnsupportedNode={replaceUnsupportedNode} />
};

Rate this page: