Dec 12, 2023

How to add hidden fields in Tina CMS

For those that use TinaCMS I will show you how to add hidden fields to the metadata of your content files.

I utilise several default fields within the YAML of my content markdown files and I wanted to add them with TinaCMS when a user creates a new entry to a collection. After I read the well written TinaCMS docs I noticed that no option existed to add default values and hide them from the user interface of TinaCMS.

I required these fields as they help me perform unique behaviour for specific types of collections such as the ability to disable the render of a content file. Whatever your reason to add default hidden values I will show you how I solved the problem.

To help illustrate the end result, I desired the fields in the code snippet below to ensure my static site generator skipped the rendering of a specific page without the end user in TinaCMS ever seeing this information:

---

_build:
  render: never

---

I will not explain the inner workings of TinaCMS, instead I will show you how to add default values to hidden fields in the steps seen below.

Step 1: Configuration of the project

You must install react and import it into your tina/config.* file otherwise you will run into errors when we will add JSX later in Step 3. The process to import JSX depends on the type of your config file, I created my TinaCMS config in pure JavaScript, therefore, I required a react import. For those with JavaScript simply install react with your package manager such as NPM and then add the following lines of code to your tina/config.js file.

import React from 'react';
import ReactDOM from 'react-dom';

If you have a different setup then I will leave it to you to understand how to best import react.

Step 2: Choose the collection and add the defaults

In your tina/config.* file select the desired collection where you want to add your default values. Once selected add a field to the root object of the collection called defaultItem, you can read more information about defaultItem on the docs

For example, as seen in my first YAML snippet in the introduction I want to add an object called _build with a field called render which contains a value of never. Therefore, I write a defaultItem with the following:

{
  name: "author",
  label: "Authors",
  path: "content/author",
  defaultItem: () => {
    return {
      _build: {
        render: "never",
      }
    }
  }
  // ...
}

Step 3: Create the hidden field

Now on this same collection, in my case author, you must create the neccessary schema fields that follow the exact same structure as the defaultItem otherwise TinaCMS will ignore the values and therefore not output it to the final content file. Also, ensure you utilise the correct TinaCMS types otherwise TinaCMS will fail silently.

In the case of the object created in Step 2, _build is an object and render is a field of type string. The field will appear as seen in the code snippet below within the fields object.

{
  name: "author",
  label: "Authors",
  path: "content/author",
  defaultItem: () => {
    return {
      _build: {
        render: "never",
      }
    }
  },
  fields: [
    {
      label: "Build",
      name: "_build",
      type: "object",
      fields: [
        {
          label: "Render",
          name: "render",
          type: "string"
        },
      ],
      ui: {
        component: ({ input }) => {
          return (
            <div class="hidden"></div>
          );
        },
      },
    }
  ]
}

As seen in the code snippet above I created another object called ui within the _build object. You must create a ui object with a field called component, the most critical step. Create a function that returns a JSX object with a div called hidden. This overrides the default TinaCMS fields on the user interface and instead returns a hidden div that will not display to the end user.

You can read more about custom fields in TinaCMS

All together now

Load up TinaCMS and create a new item in the collection where you added the default values. On creation of the new item if you successfully followed the steps it should add your custom hidden object:

---

...other YAML fields...
_build:
  render: never

---

Conclusion

I hope this tutorial helps others that desire custom hidden fields in their content files. I searched thoroughly in the documentation but found no suggested solution. The team behind TinaCMS constantly develops the project so I believe this solution will become obsolete overtime but at least this serves for the interim.

If you have other solutions to add default values feel free to message me with them and I will happily update the tutorial with a superior solution or link to alternative solutions.

Peace to everyone in the TinaCMS community and big thank you to the developers of the project, I love TinaCMS.