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
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).
After the repository is created, you will need to do the following steps to get the environment variables setup:
- 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. - Fill out the
NEXTAUTH_SECRET
environment variable with a random string.
- Git, Node.js Active LTS, Yarn installed for local development.
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
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. |
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.
- Create a Vercel account and visit the Storage tab in the dashboard.
- Click Create and select the KV (Durable Redis) option.
- Give the KV database a name, select the nearest region and click Create.
- In Quickstart, click
.env.local
and Copy Snippet to get the connection details (save these for later).
- Create a personal access token with
repo
access. (Note the expiration date of the token.) - Add the token to the
.env
file (GITHUB_PERSONAL_ACCESS_TOKEN
)
- Create a new project in Vercel and select this Git repository.
- In the Environment Variables section, you can copy and paste your entire
.env
file into the first input. - Click Deploy and wait for the project to build.
- 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.
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.
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
.
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);
};
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,
})