Custom fields are made possible by the plugin system in TinaCMS. Custom fields are a way to either add custom logic to existing fields or provide an entirely new field component

Adding Custom Logic

Adding custom logic involves two steps: first registering a field plugin and then using the field plugin in your schema.

1. Create a Field Plugin

Interface

export interface FieldPlugin<ExtraFieldProps = {}, InputProps = {}> {
  __type: 'field'
  name: string
  Component: React.FC<InputFieldType<ExtraFieldProps, InputProps>>
  type?: string
  validate?(
    value: any,
    allValues: any,
    meta: any,
    field: Field
  ): string | object | undefined
  parse?: (value: any, name: string, field: Field) => any
  format?: (value: any, name: string, field: Field) => any
  defaultValue?: any
}

Where component can be a custom component or a built in component. See here for a full list of custom components.

It is considered a good practice to have your plugins in a separate file, this allows the plugin to be lazy-loaded only when the CMS is enabled. This way it does not affect your production bundle.

// ./plugins.tsx
import { TextField } from 'tinacms'
 
export const validationPlugin = {
    Component: TextField,
    name: "text-email-validation",
    validate: (email, allValues, meta, field)=> {
       let isValidEmail = /.*@.*\..*/.test(email)
       if (!isValidEmail) return 'Invalid email address'
    },
}

2. Register a Field Plugin

The plugin can then be registered in the CMS callback in the <Tina> wrapper component.

cmsCallback={cms => {
    import('../plugins.tsx').then(({validationPlugin})=>{
        cms.plugins.add(validationPlugin)
    })
}}

3. Use Field in .tina/schema.ts

Now in the schema.ts file this field can be used for any field. It can be added to the ui property

ui: {
    component: "text-email-validation"
}

Note that the name of the field plugin must match that component used in the ui property.

Adding a Custom Field

Instead of using one of the build in fields a custom component can be provided. This can be any react component and it will render in the sidebar as a field. Follow the steps above but provide a custom Component as shown here.

List of Field Components

In general the field components can be imported from tinacms and then used as a component in your field plugin.

import { FieldComponentName } from 'tinacms'

export const MyPlugin = {
    Component: FieldComponentName,
    ...
}

Where FieldComponentName is an a Field Component from this list

Some fields must be imported from react-tinacms-editor