April 28, 2022
By Logan Anderson
Note: This post is out of date. For the latest Tina usage, see our docs.
The latest update empowers developers to put validation
,component
and parse
functions directly into the schema.
Below, if you click the "pencil" icon and edit the "Title" field, the validation function runs and gives an error to the user when it is more than 20 characters.
With this update, you can create your custom components easily; see the example below for using a custom component.
Check out this getting started guide if you want to get started with tina
To update do the following,
.tina/schema.{ts,tsx,js}
fileWe will be using the schema
file on the backend and frontend (previously, it was just the frontend), so all imports from @tinacms/cli
need to be changed to tinacms
.
defineConfig
to the schemaWe are now recommending that your config be separate from the wrapper component and placed in the schema.{ts,tsx,js}
or in its only folder.
So previously, the schema file would look like this.
export default defineSchema({// schema here})
must be changed to
import { defineConfig } from 'tinacms'export default defineConfig({// pass schema and apiUrl to the config (required) (this is how it is passed to the fronend)schema: schema,apiUrl: apiUrl,// add other config that would have previosly been in the _app.{js,tsx} file in the <TinaCMS> component.cmsCallback: (cms) => {//...},mediaStore: async () => {//...},collections: [// ...],})export default schema
You should add the following two files in the .tina/components
folder.
.tina/components/TinaProvider.js
This file handles the Tina configuration and the tina provider component, and this will only load when in edit mode, and an example below.
import TinaCMS from 'tinacms'import { tinaConfig } from '../schema.ts'// Importing the TinaProvider directly into your page will cause Tina to be added to the production bundle.// Instead, import the tina/provider/index default export to have it dynamically imported in edit-mode/**** @private Do not import this directly, please import the dynamic provider instead*/const TinaProvider = ({ children }) => {return <TinaCMS {...tinaConfig}>{children}</TinaCMS>}
.tina/components/TinaDynamicProvider.js
The TinaDynamicProvider.js
handles the loading of the TinaProvider when in "Edit mode." See the provided below
import dynamic from 'next/dynamic'const TinaProvider = dynamic(() => import('./TinaProvider'), { ssr: false })import { TinaEditProvider } from 'tinacms/dist/edit-state'const DynamicTina = ({ children }) => {return (<><TinaEditProvider editMode={<TinaProvider>{children}</TinaProvider>}>{children}</TinaEditProvider></>)}export default DynamicTina
Read more about these two files in our reference docs
_app.{js,tsx}
The last step is to update your _app.{js,tsx}
. Since the config and the provider are in a separate file, this will be less code than what was there previously.
_app.{js,tsx}
before:
import dynamic from 'next/dynamic'import { TinaEditProvider } from 'tinacms/dist/edit-state'//...const App = ({ Component, pageProps }) => {return (<><TinaEditProvidershowEditButton={true}editMode={<TinaCMScmsCallback={(cms) => {//...}}apiURL={apiURL}><Component {...pageProps} /></TinaCMS>}><Component {...pageProps} /></TinaEditProvider></>)}export default App
_app.{js,tsx}
after:
import DynamicTina from '../.tina/components/TinaDynamicProvider'const App = ({ Component, pageProps }) => {return (<DynamicTina><Component {...pageProps} /></DynamicTina>)}export default App
This separation of config into another file makes it much cleaner and easier to understand. In addition, the schema now being a part of the config and used on the frontend will allow functions to be passed and used. It will also allow us to make fewer network requests since we have more information.
The new features we talked about in this article only scratch the surface of what is possible; please read the docs to find out more.
If you are having any issues at all, please reach out to us on discord or create a github issue.
Last Edited: April 28, 2022
© TinaCMS 2019–2024