# Nextjs Tinacms

> Build Next.js 16 + React 19 + TinaCMS sites with visual editing, blocks-based page builder, and complete SEO. Use this skill whenever the user mentions TinaCMS, Tina CMS, Next.js with a CMS, visual editing with Next.js, click-to-edit, content-managed Next.js site, blocks pattern page builder, or migrating to Next.js + TinaCMS. Also trigger for TinaCMS schema design, self-hosted TinaCMS, TinaCMS media configuration, or any TinaCMS troubleshooting. Covers Day 0-2 setup from scaffolding through production deployment on Vercel.

- Skill: `genericservice/nextjs-tinacms` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add genericservice/nextjs-tinacms`
- Raw SKILL.md: https://api.skillmd.com/api/skills/genericservice/nextjs-tinacms/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Marketing & Growth
- Author: genericservice (https://skillmd.com/u/genericservice)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/genericservice/nextjs-tinacms

---


# Next.js 16 + React 19 + TinaCMS + Vercel

Opinionated for: **Next.js App Router + TinaCMS + Tina Cloud + Vercel + Tailwind CSS 4 + shadcn/ui**.

Two workflows: **New Project** (scaffold from scratch) or **Add CMS** (integrate into existing Next.js 15/16 project).

## Stack

| Technology | Version | Key Feature |
|-----------|---------|-------------|
| Next.js | 16.x | Turbopack default, `"use cache"`, `proxy.ts`, async params |
| TinaCMS | 3.x | Git-backed CMS, visual click-to-edit, GraphQL schema API, ESM-only |
| React | 19.x | Server Components, Actions, `use()`, `useEffectEvent` |
| Tailwind CSS | 4.x | CSS-first config (`@import "tailwindcss"`), no JS config needed |
| shadcn/ui | CLI v4 | Copy-paste components, `npx shadcn create`, `tw-animate-css` |
| Vercel | -- | Deploy target. `@vercel/analytics`, `@vercel/speed-insights`, Deploy Hooks |
| Tina Cloud | -- | Default CMS backend. Free tier (2 users), editorial workflow on Team Plus+ |

## Quick Start

```bash
npx create-next-app@latest my-site --typescript --tailwind --app --src-dir
cd my-site
npx @tinacms/cli@latest init
```

Verify: `tinacms dev` then open `http://localhost:3000/admin/index.html`.

**Local dev runs in local-only mode** -- content reads/writes directly to the filesystem, no Tina Cloud connection needed. Production builds connect to Tina Cloud via `NEXT_PUBLIC_TINA_CLIENT_ID` and `TINA_TOKEN` env vars on Vercel.

## Critical Knowledge

1. **Server-Client split is mandatory.** `useTina()` requires `"use client"`. Every editable page needs a Server Component (data fetcher) + Client Component (visual editing wrapper).
2. **Build order matters.** Always `"build": "tinacms build && next build"`. Wrong order breaks with `Cannot find module '../tina/__generated__/client'`.
3. **Pin exact TinaCMS versions.** No caret ranges. UI assets drift from CDN. Keep `tinacms` and `@tinacms/*` synced via package grouping (RenovateBot or Dependabot).
4. **`tina/__generated__/` should be gitignored.** Only `tina-lock.json` must be committed. The `__generated__/` folder is rebuilt by `tinacms build`.
5. **TinaCMS 3.x is ESM-only.** Config files must use `import` syntax. Set `"type": "module"` in `package.json` or use `.ts` extensions.
6. **Async params in Next.js 16.** Every `page.tsx`, `layout.tsx`, `route.ts` must `await params` -- sync access fully removed.
7. **`proxy.ts` replaces `middleware.ts`.** Lives at project root, exports `proxy` function, runs Node.js runtime only. Codemod: `npx @next/codemod@canary middleware-to-proxy .`
8. **Security: @tinacms/cli >= 2.1.8 required.** CVE-2026-28792 (Critical, CVSS 9.6) -- drive-by attacks via CORS + path traversal in older versions.
9. **Dev command is `tinacms dev -c "next dev"`.** Never `next dev` alone -- the local GraphQL server won't run.

## Version Floors

Look up current stable versions before scaffolding (`npm view <pkg> version`).

| Package | Minimum | Why |
|---------|---------|-----|
| `next` | >= 16.0.10 | Security patches |
| `tinacms` | >= 3.3.x | Visual selector, ESM-only, current schema API |
| `@tinacms/cli` | >= 2.1.8 | CVE-2026-28792 fix |
| `react` / `react-dom` | >= 19.0.x | Server Components, Actions (19.2.x for `useEffectEvent`) |
| `tailwindcss` | >= 4.x | CSS-first config (v3.4.x also acceptable) |
| Node.js | >= 20.9.0 | Next.js 16 requirement |

## Key Imports

| Import | From | Used For |
|--------|------|----------|
| `defineConfig` | `tinacms` | Schema configuration in `tina/config.ts` |
| `useTina` | `tinacms/dist/react` | Live editing in Client Components |
| `tinaField` | `tinacms/dist/react` | Click-to-edit data attributes |
| `TinaMarkdown` | `tinacms/dist/rich-text` | Rich text rendering |
| `client` | `@/tina/__generated__/client` | GraphQL queries (auto-generated) |

## Collections

Add based on project needs:

| Collection | Type | When Needed |
|-----------|------|-------------|
| `pages` | Folder + blocks | Always |
| `global` | Singleton | Always (site settings, SEO defaults) |
| `navigation` | Singleton | Always (can include footer links) |
| `posts` | Folder | If site has a blog |
| `authors` | Folder | If site has a blog |
| `footer` | Singleton | If footer warrants its own collection |
| `notFound` | Singleton | Optional |

## Common Tasks

### Create a new block

Add a template object to the blocks field's `templates` array in `tina/config.ts`. Every block needs `ui.defaultItem`. Optional: `ui.previewSrc` for visual selector thumbnails.

### Add visual editing to a page

1. Server Component fetches `{ data, query, variables }` from Tina client
2. Client Component calls `useTina()` with those props
3. Add `data-tina-field={tinaField(data.page, 'fieldName')}` on DOM elements

### Enable caching

Set `cacheComponents: true` in `next.config.ts`, then use `"use cache"` directive with `cacheLife()` presets: `seconds`, `minutes`, `hours`, `days`, `weeks`, `max`.

### Deploy to Vercel

1. Build command: `tinacms build && next build`
2. Set Vercel env vars: `NEXT_PUBLIC_TINA_CLIENT_ID`, `TINA_TOKEN`, `NEXT_PUBLIC_TINA_BRANCH`
3. Install `@vercel/analytics` + `@vercel/speed-insights`, render `<Analytics />` and `<SpeedInsights />` in root layout
4. Set up a Deploy Hook for content change rebuilds
5. Use Vercel Team Environment Variables to share keys across preview/production

**Always use Tina Cloud** unless the project has a specific reason to self-host. See `references/deployment.md` for self-hosted as a secondary option.

## Claude Code Automations

Set up in `.claude/settings.json` early in Day 0:

```json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{
        "type": "prompt",
        "prompt": "If the file path contains 'tina/__generated__/' or ends with 'tina-lock.json', BLOCK this edit. These files are auto-generated by tinacms build and must not be manually edited."
      }]
    }],
    "PostToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{
        "type": "command",
        "command": "npx prettier --write $CLAUDE_FILE_PATH 2>/dev/null || true"
      }]
    }]
  },
  "permissions": {
    "allow": [
      "Bash(npx tinacms dev:*)",
      "Bash(npx tinacms build:*)",
      "Bash(pnpm dev:*)",
      "Bash(pnpm build:*)",
      "Bash(npx shadcn@latest add:*)"
    ]
  }
}
```

**MCP servers:**
- `claude mcp add context7 -- npx -y @upstash/context7-mcp@latest` -- live TinaCMS/Next.js/React/Tailwind docs
- `claude mcp add playwright -- npx -y @anthropic-ai/mcp-server-playwright@latest` -- test visual editing in browser

**Consider creating project-level skills for repeated tasks:**
- `/new-block` -- scaffold a block template + component + renderer mapping
- `/tinacms-check` -- audit schema for missing `ui.itemProps`, broken `tinaField`, version drift

## Agentic Workflow & Vibe Coding

- **Iterative Building:** Do not expect a perfect CMS integration on the first try. Draft the schema and visual editing wrapper, test the connection locally (`tinacms dev`), isolate any specific data-fetching or rendering error, adjust exactly ONE field or query at a time, and refresh until the click-to-edit experience is seamless.
- **Vibe Coding:** Commit your working Next.js pages and Tina schema configurations locally before attempting complex block template additions or deploying to Vercel. Ensure `tina-lock.json` is included in these commits.

## Reference Files

| File | When To Read |
|------|-------------|
| `references/schema-design.md` | Designing collections, blocks, fields, content hooks |
| `references/visual-editing.md` | Server/client split, draft mode, click-to-edit debugging |
| `references/seo-meta.md` | Metadata, JSON-LD, OG tags, sitemaps, RSS |
| `references/deployment.md` | Tina Cloud vs self-hosted, media providers, env vars |
| `references/setup-checklist.md` | Phased implementation checklist (MVP / Polish / Comprehensive) |
| `templates/tina-config-starter.ts` | Production `tina/config.ts` with 5 block templates |
| `templates/page-server-client.tsx` | Server/client page pattern with metadata and static params |

