Overview

Connect TinaCMS Cloud to your GitHub repo to get visual editing for your aSaaSin site. Flow:

  • Sign in with GitHub
  • Add your existing repo as a Tina project
  • Copy Client ID & Tokens
  • Add env vars locally and on Vercel
  • Open /admin to edit.

Sign in with GitHub

  • Go to TinaCMS Cloud and sign up/in using GitHub
  • If your repo isn’t listed, install/authorize the Tina GitHub App for your user/org (GitHub will prompt you to grant access to selected repos)

Add project from your repo

  • In Tina Cloud: New Project > Git Provider: GitHub > Select your repository
  • Choose the default branch (e.g. main) and confirm the content root if prompted
  • After creation, open Project Settings and note the Client ID, Token, and optional Search Token

Environment variables

Update your local .env.local and mirror the same keys in Vercel > Project > Settings > Environment Variables. (Values come from Tina Cloud > Project Settings.)

# Tina CMS (from Tina Cloud > Project Settings)
NEXT_PUBLIC_TINA_CLIENT_ID=
TINA_TOKEN=
TINA_SEARCH_TOKEN=

Configure Tina

Ensure your Tina config reads from env and outputs the admin app (default folders shown).

// tina/config.ts
import { defineConfig } from 'tinacms'

export default defineConfig({
  branch: process.env.TINA_BRANCH || 'main',
  clientId: process.env.NEXT_PUBLIC_TINA_CLIENT_ID, // public
  token: process.env.TINA_TOKEN,                    // server secret
  search: {
    tina: {
      indexerToken: process.env.TINA_SEARCH_TOKEN,
    },
  },
  build: {
    outputFolder: 'admin',
    publicFolder: 'public',
  },
  schema: {
    // your collections go here
  },
})

Enable visual editing

Serve the prebuilt Tina admin at /admin from /public/admin/index.html (no App Router route needed). Next.js automatically serves files in public, so visiting /admin loads the UI.

Admin URL rewrite

The Next.js config rewrites /admin to /admin/index.html.

// next.config.ts
import createNextIntlPlugin from 'next-intl/plugin'

const withNextIntl = createNextIntlPlugin()

/** @type {import('next').NextConfig} */
const nextConfig = {
  async rewrites() {
    return [
      {
        source: '/admin',
        destination: '/admin/index.html',
      },
    ]
  },
}

export default withNextIntl(nextConfig)

Image hosting note

If you use Tina Media, allow its host in next.config.ts. aSaaSin’s Deployment > Overview shows the minimal images.remotePatterns with assets.tina.io. For Supabase Storage images, also whitelist your Supabase project host.

Production on Vercel

Add the same Tina env vars in Vercel (set distinct values per environment if needed). Deploy via GitHub push and verify /admin on your production domain.

Tips

  • If the repo doesn’t appear in Tina Cloud, re-check the Tina GitHub App repository access
  • Keep TINA_TOKEN server-only (no NEXT_PUBLIC_ prefix)
  • Align the Tina branch with your production branch (e.g. main)
  • Commit schema changes so the CMS stays in sync across environments