Loving Tina? us on GitHub0.0k
v.Latest
Documentation

Config Reference

Loading last updated info...
On This Page

The result of the defineConfig function when exported from tina/config.{ts,tsx,js,jsx} defines your TinaCMS setup.

Important - Config must be deterministic

The object returned by defineConfig must be evaluated multiple times during development and build. Avoid using non-deterministic values (e.g Date.now(), Math.random()) directly in config properties that affect schema or runtime configuration. This can cause GraphQL schema mismatch errors

If you need dynamic values, return a function and compute the value lazily.

Note that it must be the default export.

The location for the config file was previously at .tina/config.{ts,tsx,js,jsx}

Options

REQUIRED
schema
Schema

Defines your content model.

branch
string | null

The base branch to pull content from. Required for TinaCloud.


client​Id
string | null

TheclientId from TinaCloud. Required for TinaCloud.


token
string | null

Your read only token from TinaCloud. Required for TinaCloud.


local​Content​Path
string

The path to a separate content repo for local development, resolved relative to the tina/ config folder (not the project root).

When set, collection path values are resolved relative to this content root. The content directory must contain a tina/ folder (it can be empty) — TinaCMS writes generated files like tina-lock.json there.

Use an environment variable since the path may differ per developer:

localContentPath: process.env.TINA_CONTENT_REPO_PATH // e.g. '../../my-content-repo'

See the Separate Content Repo guide for full setup details.


auth​Provider
AuthProvider
EXPERIMENTAL
content​Api​Url​Override
string

Override the default content API URL.


telemetry
'anonymous' | 'disabled'

Controls whether TinaCMS collects anonymous usage statistics to help improve the product.

Set to 'disabled' to opt out entirely.

Default is 'anonymous'.

All properties marked as REQUIRED must be specified for the field to work properly.

Examples

Vercel and TinaCloud Configuration

This is a standard configuration using TinaCloud to host your datalayer and the built-in Tina media and search capabilities.

const branch =
process.env.NEXT_PUBLIC_TINA_BRANCH ||
process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_REF ||
process.env.HEAD ||
'main';
export default defineConfig({
branch,
// generated by TinaCloud
token: '<Your Read Only Token>',
// generated by TinaCloud
clientId: '<Your Client ID>',
build: {
publicFolder: 'public',
outputFolder: 'admin',
},
schema: {
//Content model definition here...
},
ui: {
previewUrl: (context) => {
// Use Vercel preview deployments based on branch names
return { url: `https://my-app-git-${context.branch}.vercel.app` };
},
},
media: {
tina: {
publicFolder: 'public',
mediaRoot: 'uploads',
},
},
search: {
tina: {
indexerToken: process.env.TINA_SEARCH_TOKEN,
},
},
});

Cloudinary Media Store

Tina supports both Git-backed media and specific external media providers:

export default defineConfig({
// ... other config options
media: {
loadCustomStore: async () => {
const pack = await import('next-tinacms-cloudinary');
return pack.TinaCloudCloudinaryMediaStore;
},
accept: 'image/*',
},
});

TinaCloud Search Options

Tina provides built-in search capabilities through TinaCloud.

// Tina Cloud search
export default defineConfig({
// ... other config options
search: {
tina: {
indexerToken: process.env.TINA_SEARCH_TOKEN,
stopwordLanguages: ['eng', 'fra'],
tokenSplitRegex: '/[p{L}d_]+/',
},
},
});

Environment Variables

TinaCMS uses environment variables in two contexts: the site build (your Next.js/SSG app) and the admin build (the TinaCMS editor at /admin). These have different scoping rules.

Build-Time Embedding

The Tina admin is a statically built SPA. Environment variables are embedded into the admin's JavaScript at build time (during tinacms build or tinacms dev). They are not read at runtime. This means a variable must be present in the environment when the build runs — setting it afterwards has no effect.

.env File Support

Tina's build process only picks up variables from .env files. Variables defined in .env.local, .env.development, or other dotenv variants are not loaded by the TinaCMS build. If you're deploying to a hosting provider (Vercel, Netlify, etc.), make sure the variables are also configured in that provider's environment settings.

Admin-Exposed Variables

For security, only a subset of environment variables are included in the admin build. This prevents sensitive credentials from leaking into the publicly served admin index.js.

The allowed variables are:

Pattern

Description

TINA_PUBLIC_*

TinaCMS-specific public variables

NEXT_PUBLIC_*

Next.js public variables

NODE_ENV

The current environment (development, production, etc.)

HEAD

The current branch (used by Netlify)

Any other environment variable accessed via process.env inside the admin — including custom field components, beforeSubmit hooks, or other admin-side code — will be undefined.

For an environment variable to work in the admin, it must: (1) use the TINA_PUBLIC_ or NEXT_PUBLIC_ prefix, and (2) be set in the environment when tinacms build or tinacms dev runs. For example, rename MY_API_KEY to TINA_PUBLIC_MY_API_KEY and ensure it's in your .env file or CI/hosting environment variables.

Common Environment Variables

Variable

Context

Description

NEXT_PUBLIC_TINA_CLIENT_ID

Site + Admin

Your TinaCloud project client ID

TINA_TOKEN

Site build only

Read-only token for TinaCloud (not exposed in admin)

TINA_PUBLIC_IS_LOCAL

Site + Admin

Toggle between local and production backends in self-hosted setups

NEXT_PUBLIC_TINA_BRANCH

Site + Admin

Override the branch for content fetching

TINA_SEARCH_TOKEN

Site build only

Token for TinaCloud search indexing

For more on deploying with environment variables, see Going to Production with TinaCloud. For the security background on admin variable scoping, see the February 2023 security advisory.

Imports with Typescript Path Aliases

TinaCMS supports TypeScript path aliases in the tina/config.{ts,js,tsx} file and collections.

Ensure that tsconfig.json exists at the root of your project. Define your aliases in the compilerOptions section.

//tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}

You can now import utilities or other modules using the aliases.

import { someUtility } from '@/lib/utils';
export default defineConfig({
//...
});
Last Edited: December 9, 2025