Rendering Markdown Content

When your markdown content is requested through TinaCMS's API, TinaCMS serves a parsed AST (abstract syntax tree) version of the content.

The parsed AST gives developers the ability to step through each node, and render it with full control.

The below example has some sample markdown and associated AST.

Inbuilt Markdown Rendering

TinaCMS also provides a <TinaMarkdown> component, which renders your md or mdx component from the parsed AST without having to handle the data structure yourself.

It's as easy as passing in the markdown content via the content attribute.

Styling Markdown elements

The <TinaMarkdown> component takes a components field, which takes a mapping of html element properties to react components.

When an element appears in the AST tree, it will be intercepted and replaced with the react component from the mapping.

Customizing Built-in Markdown Elements

You can also use the components prop to customize more complex elements like code_block, image, or table.

For example, you can replace code_block with your own component to support Mermaid diagrams or style code blocks the way you want.

This replaces the default <pre> block with your own React components. You can now control the code output however you like. For example, you can add syntax highlighting, line numbers, or a copy button inside your CodeBlock component.

Here's a simple CodeBlock example that uses Shiki to highlight code and adds a copy button.

MDX and Custom Elements

If you are using mdx as the format, you'll have the ability to define custom components that your editors can leverage.

How does MDX work with TinaCMS?

TinaCMS doesn't require a compilation step like other MDX tooling you might be familiar with, so it needs to know about all the possible elements you support ahead of time.

Instead of doing an import statement in MDX, you need to register each element as a template in your TinaCMS schema.

Rich-text templates

This only works for documents of the mdx format.

TinaCMS also needs to have each MDX component defined in advance, when you define your collection.

By defining the above NewsletterSignup template, our editors now have the ability to add that template to the page body.

The rich-text field also gets a new 'embed' option for adding in these components.

Linking to React components

Once you've registered a template with a rich-text field in a collection, TinaCMS still needs to know how to render the custom component. Add the key and component to the mapping you pass into the components prop on <TinaMarkdown>.

The key should match the templates name property.

Once our custom component has been registered with TinaMarkdown, editors can easily add components, and immediately see them rendered on the page.

Last Edited: July 31, 2025