Loving Tina? us on GitHub0.0k

Docs

Learn

v.Latest
Documentation
The Click-To-Edit API
Table of Contents

Tina's "click to edit" feature allows editors to select the HTML element they want to click on the page in order to see the corresponding field in the sidebar.

We can implement this with the data-tina-field API.

[data-tina-field] must be applied to HTML elements, not React components like TinaMarkdown.

API Reference

REQUIRED
object
object

The object which holds the field you're accessing.


property
string

The property from the object which you're accessing, omitting this will return the object field's metadata.

All properties marked as REQUIRED must be specified for the field to work properly.

Note: The object property only needs to contain the nearest ancestor of the field you're trying to access.

Basic Usage

// components/blocks/hero
import { tinaField } from 'tinacms/dist/react';
export const HeroComponent = (props) => {
return (
<div>
<h4 data-tina-field={tinaField(props, 'heading')}>{props.heading}</h4>
<p data-tina-field={tinaField(props, 'message')}>{props.message}</p>
<ul data-tina-field={tinaField(props, 'links')}>
{props.links.map((link) => (
<li>
<a data-tina-field={tinaField(link)} href={link.url}>
{link.label}
</a>
</li>
))}
</ul>
</div>
);
};

Custom Components and [data-tina-field]

React components can't take arbitrary HTML attributes like data-tina-field. To work around this, define a prop (e.g. tinaField) and pass it down to an HTML element inside the component:

const Section = ({ children, tinaField }) => {
return <section data-tina-field={tinaField}>{children}</section>;
};
<Section tinaField={tinaField(data, 'body')}>
<TinaMarkdown content={data.body} />
</Section>

TinaMarkdown and tinaField

When using TinaMarkdown with custom components, the props object passed into each component already includes the _content_source metadata. This metadata is automatically injected in edit mode via Tina's useTina hook.

To make a component editable, all you need to do is pass the props object directly into the tinaField helper:

<div data-tina-field={tinaField(props)}>
<MyComponent {...props} />
</div>

This links to the template component inside of TinaCMS, but does not target a specific field.

If you want to target a specific field inside the component. For example, only the format property instead of the whole block. Use the second argument to tinaField to specify the field name:

<div data-tina-field={tinaField(props, 'format')}>
Format: {props.format}
</div>

This gives Tina a more precise mapping to the field, based on the template definition defined in your collection.

Example: Using tinaField inside TinaMarkdown

Here's a slightly more advanced example showing how the tinaField can be used to expose fields within rich text content, even inside custom components:

import { useTina, tinaField } from 'tinacms/dist/react';
import { TinaMarkdown } from 'tinacms/dist/rich-text';
export default function Post(props) {
const { data } = useTina({
query: props.query,
variables: props.variables,
data: props.data,
});
return (
<div data-tina-field={tinaField(data.post, 'body')}>
<TinaMarkdown
content={data.post.body}
components={{
DateTime: (props) => {
return (
<div data-tina-field={tinaField(props)}>
<TestComp {...props} />
</div>
);
},
}}
/>
<code>
<pre>{JSON.stringify(data.post, null, 2)}</pre>
</code>
</div>
);
}
const TestComp = (props) => {
return (
<>
<div data-tina-field={tinaField(props, 'format')}>
Date Time Format: {props.format}
</div>
<div data-tina-field={tinaField(props, 'stringTest')}>
<TinaMarkdown content={props.stringTest} />
</div>
</>
);
};

This way editors can click any nested field inside custom components and go straight to that templates field.

Metadata Structure

When Tina is in edit mode, it enhances the data with metadata for each editable field. For example, a rich text template field like might look like:

{
"type": "root",
"children": [
{
"type": "DateTime",
"format": "MMM yyyy",
"stringTest": "...",
"_content_source": { // metadata
"queryId": "6rix9",
"path": [
"post",
"body",
"children",
0
]
}
}
]
}

The tinaField helper reads this _content_source metadata to construct the correct path for the editor UI to connect the field with the form.

Styling the visual editing interface

When edit mode is active, Tina automatically applies outlines to any [data-tina-field]element.

You can override these styles if needed:

.__tina-quick-editing-enabled [data-tina-field] {
outline: 2px dashed rgba(254, 34, 56, 0.5);
}
.__tina-quick-editing-enabled [data-tina-field]:hover {
outline: 2px dashed rgba(254, 34, 56, 1);
}
Last Edited: June 23, 2025