Basic TinaCMS starter based on Next.js and TinaCMS that connects to Tina Cloud Content API.
- Run this project locally using local content within this repository.
- Connect to Tina Cloud to benefit from its GraphQL Content API.
- Deploy the site to visually edit your site.
- Invite collaborators.
- โ What is this?
- ๐ด Fork and Clone
- โฌ๏ธ Install
- ๐ Run the project locally
- ๐ Edit content locally
- ๐ฆ Connect to Tina Cloud
- โฌ๏ธ Deploy
- ๐ Starter structure
- ๐ Content Modeling
- ๐ก Local development workflow tips
This is a TinaCMS-enabled Next.js app, so you can edit your content on a live page. In this project the Tina file-based CMS is used via GraphQL: it's powered by a schema that you define. It not only serves content from Markdown files in your repository, but it also generates TinaCMS forms for you automatically โจ.
Start by forking the repositorty and then pull it down to your computer.
โน๏ธ This project uses
yarn
as a package manager, ifyarn
isn't installed on your machine, open a terminal and runnpm install -g yarn
Install the project's dependencies:
yarn install
โ ๏ธ If you'd like to usenpm
beware that there is nopackage-lock.json
so we can't guarantee the dependencies are the same for you.
To run the local development server:
yarn dev
This command starts the GraphQL server and the Next.js application in development mode. It also regenerates your schema types for TypeScript and GraphQL so changes to your .tina
config are reflected immediately.
One of the most interesting aspects of the Tina Cloud Content API is that it doesn't actually require anything from the Cloud to work locally. Since Tina is by default a Git-backed CMS, everything can be run from your local filesystem via the CLI.
This is ideal for development workflows and the API is identical to the one used in the cloud, so once you're ready to deploy your application you won't face any challenges there.
Open http://localhost:3000
in your browser to see your file-based content being loaded from the GraphQL API.
We need to define some local environment variables in order to edit content with Tina.
Copy .env.local.sample
to .env.local
:
cp .env.local.sample .env.local
NEXT_PUBLIC_USE_LOCAL_CLIENT
should be set to 1
, other values can be ignored for now.
Restart your server and visit http://localhost:3000/admin
,
the same page is displayed but you can notice a pencil icon at the bottom left corner.
Click to open Tina's sidebar which displays a form with fields you can edit and see update live on the page. Since we're working locally, saving results in changes to your local filesystem.
From here, you're ready to start building your own project, to read a little bit about how this project is structured, and how to modify it to make it your own, read the folder structure section below.
When you're ready to deploy your site, read on about how you can connect to Tina Cloud and make authenticated changes via our Cloud API.
While the fully-local development workflow is the recommended way for developers to work, you'll obviously want other editors and collaborators to be able to make changes on a hosted website with authentication.
โน๏ธ Changes from the
/admin
route show up on your home page after your site finishes a rebuild.
- Visit auth.tina.io, create an organization, and sign in. Make a note of your orgnization name.
- Create an app which connects to the GitHub repository you've just forked. Once your app is created, open settings and copy the client ID.
In the env.local
file set:
NEXT_PUBLIC_USE_LOCAL_CLIENT
to0
.NEXT_PUBLIC_ORGANIZATION_NAME
to your Tina Cloud organization nameNEXT_PUBLIC_TINA_CLIENT_ID
to the Client ID displayed in your Tina Cloud App.
Restart your server and run yarn dev
again.
Open http://localhost:3000/admin
This time a modal asks you to authenticate through Tina Cloud. Upon success, your edits will be sent to the cloud server (and subsequently to GitHub).
Make some edits through the sidebar and click save. Changes are saved in your GitHub repository.
Now that Tina Cloud editing is working correctly, we can deploy the site so that other team members can make edits too.
โน๏ธ Gotcha: since your changes are being synced directly to Github, you'll notice that your non-"admin" routes still receive the unedited data from your local filesystem. This is mostly fine since editing with Tina Cloud is designed for hosted environments. But beware that changes to your schema may result in a mismatch between the Tina Cloud API and your local client.
Connect to your GitHub repository and set the same environment variables as the ones in your env.local
file:
NEXT_PUBLIC_ORGANIZATION_NAME= <YOUR_ORGANIZATION>
NEXT_PUBLIC_TINA_CLIENT_ID= <YOUR_CLIENT_ID>
๐ Congratulations, your site is now live!
You can test that everything is configured correctly by navigating to [your deployment URL]/admin
,
logging in to Tina Cloud, and making some edits. Your changes should be saved to your GitHub repository.
Connect to your GitHub repository, click on advanced to set the same environment variables as the ones in your env.local
file:
NEXT_PUBLIC_ORGANIZATION_NAME= <YOUR_ORGANIZATION>
NEXT_PUBLIC_TINA_CLIENT_ID= <YOUR_CLIENT_ID>
Set the build command to yarn build
,
Set the publish directory. To .next/
.
Once you're done, click "Deploy site".
Install the "Next on Netlify" plugin in order to take advantage of server-side rendering and Next.js preview features.
Trigger a new deploy for changes to take effect.
You can test that everything is configured correctly by navigating to [your deployment URL]/admin
,
logging in to Tina Cloud, and making some edits. Your changes should be saved to your GitHub repository.
Tina Cloud Starter is a Next.js application. The file-based routing happens through the pages
directory.
This page can be seen at http://localhost:3000/
, it loads the content from a markdown file which can be found in this repository at /content/marketing-pages/index.md
. You can edit this page at http://localhost:3000/admin
You'll find this pattern in other areas too, wherever you have a "public" page, we've created a equal "admin" version, which wraps your page in Tina. This way your public pages don't load any unnecessary Tina code.
Posts come from the content/posts
directory in this repo, and their routes are built with getStaticPaths
dynamically at build time. Again, editing them with Tina can be done by visiting the "admin" version of their URL, so to edit http://localhost:3000/posts/voteForPedro
, visit http://localhost:3000/admin/posts/voteForPedro
.
Most of the components in this project are very basic and are for demonstration purposes, feel free to replace them with something of your own!
With Tina Cloud there's no need to build forms manually like you would with TinaCMS. Instead, you're required to define a schema which acts as the single source of truth for the shape and structure of your content.
This is set up for you in ./.tina/schema.ts
, let's break down what this function is doing:
import { defineSchema } from "tina-graphql-gateway-cli";
export default defineSchema({
collections: [
{
label: "Blog Posts",
name: "posts",
path: "content/posts",
templates: [
{
label: "Article",
name: "article",
fields: [
{
type: "text",
label: "Title",
name: "title",
},
{
type: "reference",
label: "Author",
name: "author",
collection: "authors",
},
],
},
],
},
]
}
Be sure this is your default export from this file, we'll validate the schema and build out the GraphQL API with it.
The top-level key in the schema is an array of collections, a collection
informs the API about where to save content. You can see from the example that a posts
document would be stored in content/posts
, and it can be the shape of any template
from the templates
key.
Templates are responsible for defining the shape of your content, you'll see in the schema for this starter that we use templates
for sections
as well as blocks
. If you look at the landingPage
template, you'll notice that it has a set of blocks
, which are also templates.
A good way to ensure your components match the shape of your data is to leverage the auto-generated TypeScript types.
These are rebuilt when your .tina
config changes.
Tina Cloud generates your GraphQL schema automatically. ๐ช
Install GraphQL extension to benefit from type auto-completion.
Install Forestry extension to lint your YAML-based content models.
If you have a GraphQL client like Altair go to http://localhost:4001/graphql
to learn more about our GraphQL API.