rich-text typeProvides structured content which can embed custom templates that you define, much like the object type.
// .tina/schema.ts
import { defineSchema } from '@tinacms/cli'
export default defineSchema({
collections: [
{
//...
fields: [
// ...
{
type: 'rich-text',
label: 'Body',
name: 'body',
isBody: true,
templates: [
{
name: 'Cta',
label: 'Call to Action',
fields: [
{
type: 'string',
name: 'heading',
label: 'Heading',
},
],
},
],
},
],
},
],
})Given a markdown file like this:
## Hello, world!
This is some text
<Cta heading="Welcome" />Results in the following response from the content API:
Notice the
bodyresponse, it's a structured object instead of a string!
<TinaMarkdown>Since the value for rich-text is a structured object instead of a string, rendering it out to your page requires more work. We've provided a special component which is super lightweight and can used directly in your code.
// my-page.js
import { TinaMarkdown } from 'tinacms/dist/rich-text'
// The `props` here are identical to the respective template "fields"
const Cta = props => {
return (
<div>
{props.heading}
</div>
)
}
// Be sure to provide the appropriate components for each template you define
const components = {
Cta: Cta
}
export default function MyPage = (props) => {
return (
<div>
<TinaMarkdown components={components} content={props.body} />
</div>
)
}type TinaMarkdown = ({
// The rich-text data returned from the content API
content: TinaMarkdownContent
/**
* Any templates provided in the rich-text field.
* Optionally, most elements (ex. <a>) can also
* be overridden
*/
components?: Components<{}>
}) => JSX.ElementIf you've worked with MDX before, you know that there's usually a compilation step which turns your .mdx file into JavaScript code.
This works really well for developers who can access their files directly, but it creates problems when editing content from a rich-text interface.
With Tina, we're leveraging a subset of MDX to enable what's most important to content editors, and in doing so it's necessary to narrow the scope
of what's supported:
templateIn the above example, if you failed to add the Cta template in your schema definition, you would receive an error:
Found unregistered JSX or HTML: <Cta>. Please ensure all structured elements have been registered with your schema.When we say serializable, we mean that they must not be JavaScript expressions that would need to be executed at any point.
import/exportconst a = 2, console.log("Hello"))For example:
## Today is {new Date().toLocaleString()}This expression will be ignored, instead register a "Date" template:
## Today is <Date />Then you can create a Date component which returns new Date().toLocaleString() under the hood.
components yourselfTraditionally, MDX will compile whatever components you import so they're in scope when it's time to render your content.
But with Tina, MDX is completely decoupled from your JavaScript so it's up to you to ensure that for every template in your rich-text definition, there's an equivalent component in your <TinaMarkdown> component.