June 25, 2021
By Frank Taillandier
Tina adopts a developer-centric approach to structure content, which means you can model your content locally in your favourite editor. Thanks to a GraphQL layer on top of the files stored in your repository, Tina makes it more straightforward to query content all across your files. Let's see how this feels.
When we refer to Git-based, it means your content is stored in Markdown and JSON files and modelled with front matter; on top of that Tina Cloud aims to let you leverage the power of GraphQL.
We open-sourced the tina-graphql-gateway package so that you can see how it works under the hood. It contains different tools for developers to work with Tina and GraphQL:
The typical developer workflow when working on your structured content is to run Tina local GraphQL server, edit your schema, create and test queries to use those in your Next.js pages.
The GraphQL schema allows you to describe your content types or collections as we call them. At the root of the schema, you can list all your collections.
A collection points to a folder in your repository where you store a content type, like a blog post, a recipe, a book, a product, etc.
Each collection needs:
label
that will be displayed in the generated TinaCMS form,name
that will be used in the GraphQL API.description
to display a help text above the form field in TinaCMSformat
(json
for JSON files, md
for Markdown files).Let’s take a very basic example, where we declare a Blog Posts collection that points to content/posts
and we simply name our collection posts
.
To describe the shape of this content type, we need to provide a template. For our basic blog post, we’ll start by saying an article has the following front matter fields:
title
(text),author
(a reference to the author collection).We also need to define a collection for the authors, as well as a basic template for an author which has:
name
(text),avatar
(URL so text).💡 To get type autocompletion when you edit the schema install the VSCode GraphQL extension.
The corresponding schema stored in .tina/schema.ts
lools like this:
import { defineSchema } from 'tina-graphql-gateway-cli'
export default defineSchema({
collections: [
{
label: 'Blog Posts',
name: 'post',
path: 'content/posts',
templates: [
{
label: 'Article',
name: 'article',
fields: [
{
type: 'text',
label: 'Title',
name: 'title',
},
{
type: 'reference',
label: 'Author',
name: 'author',
collection: 'author',
},
],
},
],
},
{
label: 'Authors',
name: 'author',
path: 'content/authors',
templates: [
{
label: 'Author',
name: 'author',
fields: [
{
type: 'text',
label: 'Name',
name: 'name',
},
{
type: 'text',
label: 'Avatar',
name: 'avatar',
},
],
},
],
},
],
})
What type can I use?
You can use any field type available in TinaCMS: text, textarea, datetime, list, group, select, blocks, etc. (source)
Image
type is under development with Cloudinary support as a media provider with Tina Cloud.
The Tina CLI provides a command to run a local GraphQL server to watch for changes in our schema and compiles it when edited; it runs alongside Next.js in development mode. We make it our default dev
npm script in the package.json
, so that when we run yarn dev
, we have access to a GraphQL playground:
yarn dev
yarn tina-gql server:start -c "next dev"
Started Filesystem GraphQL server on port: 4001
Visit the playground at http://localhost:4001/altair/
…
When opening http://localhost:4001/altair
, the Altair GraphQL client lets you build queries and browse the API documentation.
We can query a blog post by passing its relative path to the collection defined in content/posts
and get data from our fields like so:
query BlogPost {
getPostDocument(relativePath: "myBlogPost.md") {
data {
__typename
... on Article_Doc_Data {
title
author {
data {
... on Author_Doc_Data {
name
avatar
}
}
}
_body
}
}
}
}
Now that we know how to query data from our files, we still need to use that query in our Next.js application, request it from the client and ask Tina to generate the corresponding form so that our contributors are able to edit it visually. We'll detail the remaining steps in a follow-up post, stay tuned!
Join our Discord, if you have any question regarding how to work with Tina and Next.js.
Last Edited: June 25, 2021