Add EmDash to an Existing Astro Project
npm create emdash@latest ships a pre-wired project, but EmDash also grafts onto an Astro site you already have. This guide walks through every requirement the starter template normally handles for you — each one produces a confusing failure when it’s missing, so work through the checklist in order.
Prerequisites
Section titled “Prerequisites”- Astro 6 or later — upgrade first if you’re on an older major (
npx @astrojs/upgrade) - Node.js v22.12.0 or higher (odd-numbered versions are not supported)
- Server output — EmDash serves content at runtime, so your project needs
output: "server"and an adapter (Node, Cloudflare, …)
Install the Packages
Section titled “Install the Packages”Install EmDash together with its required peer dependencies. React powers the admin UI at /_emdash/admin; it is required even if your site itself doesn’t use React.
npm install emdash @astrojs/react react react-dompnpm add emdash @astrojs/react react react-domyarn add emdash @astrojs/react react react-domFor a local SQLite database (the default for development), also install the driver:
npm install better-sqlite3Deploying to Cloudflare? Add the Cloudflare packages as well — the Deploy to Cloudflare guide covers them in detail:
npm install @astrojs/cloudflare @emdash-cms/cloudflareRegister the Integrations
Section titled “Register the Integrations”Add both react() and emdash() to your integrations array. Registering @astrojs/react is not optional: installing the package alone is not enough, and without the integration the admin builds fine but never hydrates — the page sits on “Loading EmDash…” forever.
import { defineConfig } from "astro/config";import node from "@astrojs/node";import react from "@astrojs/react";import emdash, { local } from "emdash/astro";import { sqlite } from "emdash/db";
export default defineConfig({ output: "server", adapter: node({ mode: "standalone" }), integrations: [ react(), emdash({ database: sqlite({ url: "file:./data.db" }), storage: local({ directory: "./uploads", baseUrl: "/_emdash/api/media/file", }), }), ],});Add the Live Collections Loader
Section titled “Add the Live Collections Loader”Create src/live.config.ts so Astro’s content layer can resolve EmDash content. Without it, getEmDashCollection / getEmDashEntry have no live collection to route through.
import { defineLiveCollection } from "astro:content";import { emdashLoader } from "emdash/runtime";
export const collections = { _emdash: defineLiveCollection({ loader: emdashLoader() }),};Your existing src/content.config.ts (file-based collections) keeps working alongside it — see EmDash for Astro Developers for how the two coexist.
Verify the Install
Section titled “Verify the Install”-
Start the dev server:
Terminal window npm run dev -
Open
http://localhost:4321/_emdash/adminand complete the Setup Wizard. -
Create and publish a post, then query it from a page:
src/pages/test.astro ---import { getEmDashCollection } from "emdash";const { entries: posts } = await getEmDashCollection("posts", {status: "published",});---<ul>{posts.map((post) => <li>{post.data.title}</li>)}</ul>
Deploying to Cloudflare
Section titled “Deploying to Cloudflare”Follow Deploy to Cloudflare for the full setup (D1 database, R2 media bucket, cron triggers). Two things trip up existing projects in particular:
- Use Cloudflare Workers, not Pages. The
@astrojs/cloudflareadapter emits awrangler.jsonthat Pages does not accept. If your site currently deploys to Pages, migrate it to Workers first. - Bindings must exist in your
wrangler.jsonc. At minimum you need a D1 binding for the database and an R2 binding for media, matching the binding names in yourastro.config.mjs.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Cause | Fix |
|---|---|---|
| Admin stuck on “Loading EmDash…” | @astrojs/react not registered | Add react() to integrations |
Could not resolve "astro:content" in live.config.ts | Astro older than 6 | Upgrade Astro |
getEmDashCollection returns an error | Missing src/live.config.ts | Add the live collections loader |
| Build errors about unresolved packages | Peer dependencies not installed | Install @astrojs/react, react, react-dom explicitly |
| Content changes don’t appear | Page is prerendered | Set export const prerender = false on dynamic pages |
Next Steps
Section titled “Next Steps”- EmDash for Astro Developers — How EmDash concepts map onto what you already know
- Working with Content — Query and render content
- Deploy to Cloudflare — Take the site to production