When you define a collection, TinaCMS gives you access to a full-page editor window to add your content.
Tina also allows for "Visual Editing" when used with React. This is a setup that allows your website and editor window to sit side-by-side, showing your changes in real-time.
Visual Editing Requirements – before a page can be setup with visual editing, it first needs to be using Tina's data-fetching.
For pages to update as you edit, you'll need to re-hydrate the page data. In React, (or react based frameworks like NextJS) you can configure a page for Visual Editing with the useTina
hook.
This hook can be associated to content areas in your code, and registers the corresponding fields in your sidebar and for re-hydration.
In production, this hook will only pass through its initial data value.
useTina
should be provided three parameters:
query
and variables
: These are the same values that you used for backend data-fetching. The query must be for an individual document only.data
: This is the GraphQL response you received from the Tina API.If you used the Tina client functions for data fetching, the three return values can be plugged directly into theuseTina
hook.
// ...import { useTina } from 'tinacms/dist/react';export default function Home(props) {// Pass our data through the "useTina" hook to make it editableconst { data } = useTina({query: props.query,variables: props.variables,data: props.data,});// Note how our page title uses "data", and not the original "props.data".// This ensures that the content will be updated in edit-mode as the user typesreturn <h1>{data.page.title}</h1>;}export const getStaticProps = async () => {const pageResponse = await client.queries.page({ relativePath: 'home.mdx' });return {props: {data: pageResponse.data,query: pageResponse.query,variables: pageResponse.variables,},};};
Tina's experimental Select Form By ID feature allows developers to choose which form shows in the visual editing sidebar when multiple useTina
hooks (or queries) exist on a page. By default, the first query requested is used to determine the form. However, by using this feature, you can ensure that a specific form — such as the one associated with a page collection rather than a global config — is used in the Tina sidebar. This can be particularly useful when working with multiple domains, where distinct sections or areas of your site require different form configurations.
When initializing the useTina
hook, you can pass an experimental callback named experimental___selectFormByFormId()
. This callback should return a unique form identifier, which tells Tina which document’s form should be shown in visual editing.
export default function PageComponent(props: PageComponentProps) {const { data } = useTina({query: props.query,variables: props.variables,data: props.data,experimental___selectFormByFormId() {return `content/pages/${props.variables.relativePath}`;},});// ...rest of the component code}
In the example above, the callback generates a form ID using the page's relativePath
, ensuring that the appropriate form is used for editing in the sidebar.
© TinaCMS 2019–2025