We use cookies to improve your experience. By continuing, you agree to our use of cookies. Learn More

Tina Docs
Introduction
Core Concepts
Querying Content
Editing
Customizing Tina
Going To Production
Media
Drafts
Guides
Further Reference

object Type

The object field is a dynamic field type that creates a nested page in the CMS with the data it contains.

This can be used to create repeated data structures, group related data in the CMS and/or give users the option to choose between a set of templates.

type ObjectField = {
label: string
name: string
type: 'object'
list?: boolean
// `fields` OR `templates` may be provided, not both
fields?: Field[]
templates?: Template[]
/** Customize the default "_template" key that gets set
in a document to identify a block-type.
Only applicable when list: true **/
templatesKey?: string
// See https://tina.io/docs/extending-tina/overview/ for customizing the UI
ui?: {
// Whether or not the Visual Selector is enabled. See https://tina.io/docs/editing/blocks/#adding-a-visual-block-selector-experimental
visualSelector?: boolean,
// defaultItem can only can be used when {list: true}
defaultItem?: Record<string, any> | () => Record<string, any>,
itemProps?(
item: Record<string, any>
): {
label?: string
}
}
}

Usage

Ultimately there are 3 ways to configure this type...

  • With list set to false, the fields array can be used to wrap some data – this appears in the editor as a nested page. This can be used to organise the CMS, such as grouping options together, as in the gif below.
  • With list set to true, the fields array contains the data structure to be repeated – this appears in the editor as above, but grouped as a list.
  • With list set to true, and using templates as opposed to fields the user can select between associated templates – this appears as above, but pressing the + gives you the option to choose between templates.
Scenario: We have a component on our site that needs to hold an array of other field types, so we define it as a type object. Some of the field types within this parent object are also objects themselves.
import type { Template, TinaField } from 'tinacms';
export const featuresTemplate: Template = {
label: 'Feature Block',
name: 'featureBlock',
fields: [
{
name: 'featureItem',
label: 'Feature Items',
type: 'object',
list: true,
ui {
itemProps: (item) => {
return { label: item?.headline };
},
},
fields: [
{ name: 'headline', label: 'Headline', type: 'string' },
{
name: 'description', label: 'Description',
type: 'string', ui: { component: 'textarea' }
},
{
name: 'buttons',
label: 'Buttons',
list: true,
type: 'object',
ui: {
visualSelector: true,
itemProps: (item) => {
return { label: item?.label };
},
},
templates: [
actionsButtonTemplate as Template,
codeButtonTemplate as Template,
modalButtonTemplate as Template
],
},
] as TinaField[],
},
],
};

Code-Block Breakdown

  • We originally have a list of feature item objects, each of these objects store an array [Headline, description, buttons]
  • Each feature item in the list has a dynamic label so that we can differentiate between each feature item in our editor (lines 12-14)
  • We then have some reusable objects which are stored as a list within our buttons element of the featureBlock array
  • Because each of our unique 3 button templates also stores an array of variables themself, we use the type: object

An example of what this object array would look like is

{
'headline': 'Feature Item 1',
'description': 'All stuff Tina!',
'buttons': [
{
label: 'Button A',
href: '/docs',
},
{
label: 'Button B',
href: '/blog'
}
],
},
{
'headline': 'Feature Item 2',
'description': 'This feature has no buttons'
}

More Examples

Tina will generate the appropriate component depending on the configuration provided.

A basic object configuration

{
label: "Testimonial",
name: "testimonial",
type: "object",
fields: [
{
label: "Author",
name: "author",
type: "string"
},
{
label: "Role",
name: "role",
type: "string"
},
{
label: "Quote",
name: "quote",
type: "string",
ui: {
component: "textarea"
}
}
]
}

As a list with default values

{
label: "Testimonials",
name: "testimonials",
type: "object",
list: true,
ui: {
itemProps: (item) => {
return { label: `${item?.author} ( ${item?.role} ) ` }
},
defaultItem: {
author: "Judith Black",
role: "CEO",
quote: "Lorem ipsum dol..."
}
},
fields: [
{
name: "author",
// ...
},
{
name: "role",
// ...
},
{
name: "quote",
// ...
}
]
}

Using list object as a wrapper for other types

Number, boolean, datetime, reference and rich-text field types can be used as the sole field of an object to create a list of one of those types.

{
label: "Author List",
name: "authorList",
type: "object",
list: true,
fields: [
{
label: 'Author',
name: 'author',
type: 'reference',
collections: ['author'],
},
]
}

Using templates instead of fields

{
label: "Page Blocks",
name: "pageBlocks",
type: "object",
list: true,
templates: [
{
label: "CTA",
name: "cta",
fields: [...]
},
{
label: "Testimonial",
name: "testimonial",
fields: [...]
}
]
}

Last Edited: November 26, 2024