Astro + Tina Setup Guide
TinaCMS runs side-by-side with Astro, with first-class visual editing that requires no React in your page tree. The integration ships as @tinacms/astro (a vanilla-Astro rich-text renderer plus a one-line Astro integration) and @tinacms/bridge (a small postMessage client that loads only inside the editor iframe).
This guide walks through local setup, content modeling, running TinaCMS, and wiring visual editing.
Getting Started
1. Initialize TinaCMS in Your Astro Site
From within your site's root directory, run:
npx @tinacms/cli@latest init
This command will prompt you with a few setup questions. When asked for the public assets directory, enter:
public
Alternatively, scaffold from the React-free starter template:
npx create-tina-app@latest --template tina-astro-starter
This sets up a blog-ready Astro Starter Template with TinaCMS and visual editing preconfigured, no React in the source tree.
Modeling Your Content
Define your content models in tina/config.ts. See the content modeling docs for the full schema reference.
Running TinaCMS
Start the dev server alongside Astro:
npx tinacms dev -c "astro dev"
Note:--port 8080can be added afterastro devto specify a custom port.
Once running, navigate to:
http://localhost:<port>/admin/index.htmlor/admin (If using the Tina Astro Starter, which redirects to /admin/index.html)
Tip: If you encounter errors, check the Common Errors page.
You should now see the Tina admin interface, be able to select a post, save changes, and observe updates persisting to your local markdown files.

Enabling Visual Editing
Visual editing (click-to-focus, live preview as the editor types, side-by-side admin + page) works on Astro without React via the @tinacms/astro package. The starter has it preconfigured. For an existing site:
pnpm add @tinacms/astro tinacmspnpm add @astrojs/node # or @astrojs/vercel / netlify / cloudflare
Then in astro.config.mjs:
import { defineConfig } from 'astro/config';import tina from '@tinacms/astro/integration';import node from '@astrojs/node';export default defineConfig({output: 'server',adapter: node({ mode: 'standalone' }),integrations: [tina()],});
That single tina() call auto-injects the request-scoped middleware (which splices the bridge wiring on edit-mode responses) and stages the vanilla-JS bridge as a static file at /admin/bridge.js. Production HTML is byte-identical to a Tina-free Astro app.
You need an SSR adapter. The per-island refresh endpoint (/tina-island/[name]) runs at request time. Use@astrojs/node,@astrojs/vercel,@astrojs/netlify, or@astrojs/cloudflare.output: 'server'is the simplest choice;output: 'static'also works as long as editable regions are wrapped in<TinaIsland>(the package's marker component) and the adapter can serve the one on-demand island route.
The full wiring (requestWithMetadata() data loaders, the island registry, <TinaIsland> wrappers, tinaField() markers, the per-island endpoint) is documented in Visual Editing Setup → Astro.

Project Structure
The starter and the visual-editing setup organize around four moving pieces:
src/lib/:data.ts(per-collection fetchers — each one calls the generated Tina client and pipes the result throughrequestWithMetadata()from@tinacms/astro/data),islands.ts(registry of editable regions consumed byexperimental_createIslandRoute).src/pages/tina-island/[name].ts: the dynamic endpoint the bridge POSTs to on every keystroke. One line:experimental_createIslandRoute(islands).src/components/islands/*.astro: pure Astro renderers (<TinaMarkdown>for rich-text,tinaField()for click-to-edit markers).astro.config.mjs: registers thetina()integration; the middleware handles bridge injection automatically — no shared<head>wiring component to maintain.
See Visual Editing Setup → Astro for the full architecture.
Next Steps
- Visual Editing Setup → Astro: the integration, per-island refetch, and custom MDX embeds
- Migrating from React-based Visual Editing: for existing Astro sites on the old
client:tinapath
For more details, visit the official TinaCMS documentation and Astro documentation. Join the TinaCMS Discord for community support.
See Also
- Next.js setup guide - Using Tina with Next.js
- Hugo setup guide - Using Tina with Hugo
- Self-hosting options - Host Tina on your own infrastructure