Note: Building with Tina and Gatsby currently requires that you run a development server for content-editing. We recommend using Next.js for a solution with less friction.
After adding gatsby-plugin-tinacms
to our site we can create forms by calling the useForm
hook inside our BlogPostTemplate
component.
While there are a few helpers for creating forms depending on your data and framework, the the first hook you should get familiar with is useForm
, as it's not Gatsby-specific and is the most generic way to register any form with the CMS.
The useForm
hook returns two values in an array, similar to React.useState
, which we assign via destructuring:
const [modifiedValues, form] = useForm(formConfig)
modifiedValues
contains the values we provide to the form (inside of formConfig
) after being modified by the end user. form
contains the form object created by calling useForm
, which we'll need in a moment.
For details on how to configure forms, take a look at our form configuration docs. For the purposes of this guide, we will use the following configuration:
const formConfig = {
id: data.markdownRemark.id, // a unique identifier for this instance of the form
label: 'Blog Post', // name of the form to appear in the sidebar
initialValues: data.markdownRemark, // populate the form with starting values
onSubmit: (values) => { // do something with the data when the form is submitted
alert(`Submitting ${values.frontmatter.title}`)
},
fields: [ // define fields to appear in the form
{
name: 'frontmatter.title', // field name maps to the corresponding key in initialValues
label: 'Title', // label that appears above the field
component: 'text', // the component used to handle UI and input to the field
},
{
name: 'frontmatter.description',
label: 'Description',
component: 'textarea', // `component` accepts a predefined components or a custom React component
},
]
}
Note that our
onSubmit
handler is just a stub. How you implement this function will depend on how your content is stored, and will be explored in later guides.
First, we'll need to import useForm
and usePlugin
from the tinacms
package. useForm
creates the form, and usePlugin
registers the form (as a plugin) with the CMS:
src/templates/blog-post.js
import { useForm, usePlugin } from 'tinacms'
Now, just add the form to the BlogPostTemplate
component with the configuration we laid out previously. To simplify setup, we'd like to instead give modifiedValues
the variable name post
so that our layout code can continue to work without modification:
src/templates/blog-post.js
const BlogPostTemplate = ({ data, pageContext, location }) => {
const formConfig = {
id: data.markdownRemark.id,
label: "Blog Post",
initialValues: data.markdownRemark,
onSubmit: values => {
alert(`Submitting ${values.frontmatter.title}`)
},
fields: [
{
name: "frontmatter.title",
label: "Title",
component: "text",
},
{
name: "frontmatter.description",
label: "Description",
component: "textarea",
},
],
}
// Create the form
const [post, form] = useForm(formConfig)
const siteTitle = data.site.siteMetadata.title
const { previous, next } = pageContext
return (
//...
)
}
At this point, the form is all wired up with its field configuration, and our post
object will send updated values back through our layout rendering code. However, if you've followed along this far, you'll see that the form does not appear in the Tina sidebar.
In order to hook our form into the CMS, we'll need to call usePlugin
and pass it our form object:
// Create the form
const [post, form] = useForm(formConfig)
// Register it with the CMS
+ usePlugin(form)
That's it — You should be able to edit the title and description of this page in the sidebar!
Why do we need to call usePlugin?
There are a few different ways to use forms: in the sidebar, in the global utility menu, and inline. How you plan to use the form will determine how you should set it up in the CMS.
Last Edited: October 16, 2020