Claude
Skills
Sign in
Back

tinacms

Included with Lifetime
$97 forever

Build content-heavy sites with Git-backed TinaCMS. Provides visual editing and content management for blogs, documentation, and marketing sites with non-technical editors. Use when implementing Next.js, Vite+React, or Astro CMS setups, self-hosting on Cloudflare Workers, or troubleshooting ESbuild compilation errors, module resolution issues, or Docker binding problems.

Web Devscriptsassets

What this skill does


# TinaCMS Skill

Complete skill for integrating TinaCMS into modern web applications.

---

## What is TinaCMS?

**TinaCMS** is an open-source, Git-backed headless content management system (CMS) that enables developers and content creators to collaborate seamlessly on content-heavy websites.

### Key Features

1. **Git-Backed Storage**
   - Content stored as Markdown, MDX, or JSON files in Git repository
   - Full version control and change history
   - No vendor lock-in - content lives in your repo

2. **Visual/Contextual Editing**
   - Side-by-side editing experience
   - Live preview of changes as you type
   - WYSIWYG-like editing for Markdown content

3. **Schema-Driven Content Modeling**
   - Define content structure in code (`tina/config.ts`)
   - Type-safe GraphQL API auto-generated from schema
   - Collections and fields system for organized content

4. **Flexible Deployment**
   - **TinaCloud**: Managed service (easiest, free tier available)
   - **Self-Hosted**: Cloudflare Workers, Vercel Functions, Netlify Functions, AWS Lambda
   - Multiple authentication options (Auth.js, custom, local dev)

5. **Framework Support**
   - **Best**: Next.js (App Router + Pages Router)
   - **Good**: React, Astro (experimental visual editing), Gatsby, Hugo, Jekyll, Remix, 11ty
   - **Framework-Agnostic**: Works with any framework (visual editing limited to React)

### Current Versions

- **tinacms**: 2.9.0 (September 2025)
- **@tinacms/cli**: 1.11.0 (October 2025)
- **React Support**: 19.x (>=18.3.1 <20.0.0)

---

## When to Use This Skill

### ✅ Use TinaCMS When:

1. **Building Content-Heavy Sites**
   - Blogs and personal websites
   - Documentation sites
   - Marketing websites
   - Portfolio sites

2. **Non-Technical Editors Need Access**
   - Content teams without coding knowledge
   - Marketing teams managing pages
   - Authors writing blog posts

3. **Git-Based Workflow Desired**
   - Want content versioning through Git
   - Need content review through pull requests
   - Prefer content in repository with code

4. **Visual Editing Required**
   - Editors want to see changes live
   - WYSIWYG experience preferred
   - Side-by-side editing workflow

### ❌ Don't Use TinaCMS When:

1. **Real-Time Collaboration Needed**
   - Multiple users editing simultaneously (Google Docs-style)
   - Use Sanity, Contentful, or Firebase instead

2. **Highly Dynamic Data**
   - E-commerce product catalogs with frequent inventory changes
   - Real-time dashboards
   - Use traditional databases (D1, PostgreSQL) instead

3. **No Content Management Needed**
   - Application is data-driven, not content-driven
   - Hard-coded content is sufficient

---

## Setup Patterns by Framework

Use the appropriate setup pattern based on your framework choice.

### 1. Next.js Setup (Recommended)

#### App Router (Next.js 13+)

**Steps:**

1. **Initialize TinaCMS:**
   ```bash
   npx @tinacms/cli@latest init
   ```
   - When prompted for public assets directory, enter `public`

2. **Update package.json scripts:**
   ```json
   {
     "scripts": {
       "dev": "tinacms dev -c \"next dev\"",
       "build": "tinacms build && next build",
       "start": "tinacms build && next start"
     }
   }
   ```

3. **Set environment variables:**
   ```env
   # .env.local
   NEXT_PUBLIC_TINA_CLIENT_ID=your_client_id
   TINA_TOKEN=your_read_only_token
   ```

4. **Start development server:**
   ```bash
   npm run dev
   ```

5. **Access admin interface:**
   ```
   http://localhost:3000/admin/index.html
   ```

**Key Files Created:**
- `tina/config.ts` - Schema configuration
- `app/admin/[[...index]]/page.tsx` - Admin UI route (if using App Router)

**Template**: See `templates/nextjs/tina-config-app-router.ts`

---

#### Pages Router (Next.js 12 and below)

**Setup is identical**, except admin route is:
- `pages/admin/[[...index]].tsx` instead of app directory

**Data Fetching Pattern:**
```tsx
// pages/posts/[slug].tsx
import { client } from '../../tina/__generated__/client'
import { useTina } from 'tinacms/dist/react'

export default function BlogPost(props) {
  // Hydrate for visual editing
  const { data } = useTina({
    query: props.query,
    variables: props.variables,
    data: props.data
  })

  return (
    <article>
      <h1>{data.post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: data.post.body }} />
    </article>
  )
}

export async function getStaticProps({ params }) {
  const response = await client.queries.post({
    relativePath: `${params.slug}.md`
  })

  return {
    props: {
      data: response.data,
      query: response.query,
      variables: response.variables
    }
  }
}

export async function getStaticPaths() {
  const response = await client.queries.postConnection()
  const paths = response.data.postConnection.edges.map((edge) => ({
    params: { slug: edge.node._sys.filename }
  }))

  return { paths, fallback: 'blocking' }
}
```

**Template**: See `templates/nextjs/tina-config-pages-router.ts`

---

### 2. Vite + React Setup

**Steps:**

1. **Install dependencies:**
   ```bash
   npm install react@^19 react-dom@^19 tinacms
   ```

2. **Initialize TinaCMS:**
   ```bash
   npx @tinacms/cli@latest init
   ```
   - Set public assets directory to `public`

3. **Update vite.config.ts:**
   ```typescript
   import { defineConfig } from 'vite'
   import react from '@vitejs/plugin-react'

   export default defineConfig({
     plugins: [react()],
     server: {
       port: 3000  // TinaCMS default
     }
   })
   ```

4. **Update package.json scripts:**
   ```json
   {
     "scripts": {
       "dev": "tinacms dev -c \"vite\"",
       "build": "tinacms build && vite build",
       "preview": "vite preview"
     }
   }
   ```

5. **Create admin interface:**

   **Option A: Manual route (React Router)**
   ```tsx
   // src/pages/Admin.tsx
   import TinaCMS from 'tinacms'

   export default function Admin() {
     return <div id="tina-admin" />
   }
   ```

   **Option B: Direct HTML**
   ```html
   <!-- public/admin/index.html -->
   <!DOCTYPE html>
   <html>
     <head>
       <meta charset="utf-8" />
       <title>Tina CMS</title>
       <meta name="viewport" content="width=device-width, initial-scale=1" />
     </head>
     <body>
       <div id="root"></div>
       <script type="module" src="/@fs/[path-to-tina-admin]"></script>
     </body>
   </html>
   ```

6. **Use useTina hook for visual editing:**
   ```tsx
   import { useTina } from 'tinacms/dist/react'
   import { client } from '../tina/__generated__/client'

   function BlogPost({ initialData }) {
     const { data } = useTina({
       query: initialData.query,
       variables: initialData.variables,
       data: initialData.data
     })

     return (
       <article>
         <h1>{data.post.title}</h1>
         <div>{/* render body */}</div>
       </article>
     )
   }
   ```

7. **Set environment variables:**
   ```env
   # .env
   VITE_TINA_CLIENT_ID=your_client_id
   VITE_TINA_TOKEN=your_read_only_token
   ```

**Template**: See `templates/vite-react/`

---

### 3. Astro Setup

**Steps:**

1. **Use official starter (recommended):**
   ```bash
   npx create-tina-app@latest --template tina-astro-starter
   ```

   **Or initialize manually:**
   ```bash
   npx @tinacms/cli@latest init
   ```

2. **Update package.json scripts:**
   ```json
   {
     "scripts": {
       "dev": "tinacms dev -c \"astro dev\"",
       "build": "tinacms build && astro build",
       "preview": "astro preview"
     }
   }
   ```

3. **Configure Astro:**
   ```javascript
   // astro.config.mjs
   import { defineConfig } from 'astro/config'
   import react from '@astro/react'

   export default defineConfig({
     integrations: [react()]  // Required for Tina admin
   })
   ```

4. **Visual editing (experimental):**
   - Requires React components
   - Use `client:tinaDirective` for interactive editing
   - Full visual editing is experimental as of October 2025

5. **Set environment variables:**
   ```env
   # .env
   PUBL
Files: 24
Size: 103.0 KB
Complexity: 96/100
Category: Web Dev

Related in Web Dev