Tina Self Hosted Demo 🦙

This is a A Next.js + TinaCMS starter site designed to be hosted on entirely on Vercel (with Markdown in GitHub). Please check out the docs for more information on self-hosting TinaCMS.

Watch a 1-min demo https://www.youtube.com/watch?v=h6LoJS3FFOA

Youtube video

Vercel Quick Start

Use the following link to directly deploy this demo to Vercel. You will need a Vercel account and a GitHub personal access token (PAT) with access to the repository (once it has been created).

Deploy with Vercel

Environment Variable Setup

After the repository is created, you will need to do the following steps to get the environment variables setup:

  1. Create a new GitHub personal access token (PAT) with content access to the new repository and copy the token as the value for the GITHUB_PERSONAL_ACCESS_TOKEN environment variable.
  2. Fill out the NEXTAUTH_SECRET environment variable with a random string.

Local Development

Requirements

Set up the .env file:

cp .env.example .env

Fill in the .env file with your own values.

Hint: NEXTAUTH_SECRET can be generated with openssl rand -base64 32

GITHUB_OWNER=***
GITHUB_REPO=***
GITHUB_BRANCH=***
GITHUB_PERSONAL_ACCESS_TOKEN=***

NEXTAUTH_SECRET=***

Install the project's dependencies:

yarn install

Run the project locally:

This will start TinaCMS in "Local Mode", meaning all changes will be made to the local file system and no auth is required.

yarn dev

Run the project locally with Vercel KV:

This will start TinaCMS in "Production Mode", meaning all changes will be made to the Vercel KV, and GitHub. Database and auth are required.

First add the following environment variables to your .env file:

# Get these from vercel if you want to run yarn dev:prod
KV_REST_API_URL=***
KV_REST_API_TOKEN=***

Then run the following command:

yarn dev:prod

Environment Variables

Variable Description
GITHUB_OWNER The owner of the repository you want to use for your content. Required in local development. Defaults to VERCEL_GIT_REPO_OWNER in Vercel.
GITHUB_REPO The name of the repository you want to use for your content. Required in local development. Defaults to VERCEL_GIT_REPO_SLUG in Vercel.
GITHUB_BRANCH The branch of the repository you want to use for your content. Defaults to VERCEL_GIT_COMMIT_REF or main if not specified.
GITHUB_PERSONAL_ACCESS_TOKEN A personal access token with repo access.
NEXTAUTH_SECRET A secret used by NextAuth.js to encrypt the NextAuth.js JWT.
KV_REST_API_URL The URL of the Vercel KV database.
KV_REST_API_TOKEN The token for authenticating to the Vercel KV database.
NEXT_PUBLIC_TINA_CLIENT_ID The client id for your Tina Cloud application. Only required for Tina Cloud authorization.

Deploying to Vercel

This demo is configured with default username / password authentication backed by Vercel KV. Other NextAuth providers can be used, as well other auth solutions such as Clerk.

Setting up Vercel KV

  1. Create a Vercel account and visit the Storage tab in the dashboard.
  2. Click Create and select the KV (Durable Redis) option.
  3. Give the KV database a name, select the nearest region and click Create.
  4. In Quickstart, click .env.local and Copy Snippet to get the connection details (save these for later).

Animation showing how to setup Vercel KV

Create a GitHub personal access token

  1. Create a personal access token with repo access. (Note the expiration date of the token.)
  2. Add the token to the .env file (GITHUB_PERSONAL_ACCESS_TOKEN)

Animation showing how to create a personal access token

Deploying the project in Vercel

  1. Create a new project in Vercel and select this Git repository.
  2. In the Environment Variables section, you can copy and paste your entire .env file into the first input.
  3. Click Deploy and wait for the project to build.
  4. Visit the project URL and navigate to /admin/index.html to log in. The default username and password can be found in content/users/index.json. After your first login, be sure to update your password.

Animation showing deployment to Vercel

Using Tina Cloud for Authorization

Tina Cloud can be used to manage users and authorization for your TinaCMS application. To use Tina Cloud for auth, you will need to create a new project in the Tina Cloud dashboard. You will be required to specify a repository, but since the data layer is managed by Vercel KV, you can use any repository.

Configuration

Once you have created an application, you will need to add the following environment variable to your project:

NEXT_PUBLIC_TINA_CLIENT_ID=***

The value for NEXT_PUBLIC_TINA_CLIENT_ID can be found in the Tina Cloud dashboard on the "Overview" page for your project.

In your Tina configuration, first remove or comment out the authProvider property.

Then, confirm that the following property is set in the Tina config:

```js
{
...
clientId: process.env.NEXT_PUBLIC_TINA_CLIENT_ID,
}
```

Lastly, remove or comment out the TinaUserCollection from schema.collections.

Updating the Backend

The backend is configured with the AuthJsBackendAuthProvider by default. To use Tina Cloud, you will need to update the backend to use the TinaCloudBackendAuthProvider. The GraphQL endpoint is configured to use Auth.js by default. To use Tina Cloud, you will need to update the endpoint in pages/api/tina/[...routes].ts to use Tina Cloud's auth. The updated file should look like this after the change:

import { TinaNodeBackend, LocalBackendAuthProvider } from "@cms/datalayer";
import { TinaCloudBackendAuthProvider } from "@tinacms/auth";

import databaseClient from "../../../tina/__generated__/databaseClient";

const isLocal = process.env.TINA_PUBLIC_IS_LOCAL === "true";

const handler = TinaNodeBackend({
  authProvider: isLocal
    ? LocalBackendAuthProvider()
    : TinaCloudBackendAuthProvider(),
  databaseClient,
});

export default (req, res) => {
  // Modify the request here if you need to
  return handler(req, res);
};

Using MongoDB for the datalayer

It's possible to use MongoDB with the data layer for your TinaCMS application instead of Vercel KV. To do this, you will need to add the following environment variables to your project:

`MONGODB_URI` is the connection string to your MongoDB database. You can use [MongoDB Atlas](https://www.mongodb.com/cloud/atlas) to get a free database.

Next you will need to update the tina/database.ts to use the MongoDB level implementation instead of the Redis level implementation.

import { MongodbLevel } from "mongodb-level"
...
const mongodbLevelStore = new MongodbLevel<string, Record<string, any>>({
  collectionName: "tinacms",
  dbName: "tinacms",
  mongoUri: process.env.MONGODB_URI as string,
})

export default isLocal
  ? createLocalDatabase()
  : createDatabase({
    gitProvider: new GitHubProvider({
      branch,
      owner,
      repo,
      token,
    }),
    databaseAdapter: mongodbLevelStore,
    namespace: branch,
  })