How to Connect EmDash CMS with Next.js

Worth stating plainly before anything else: EmDash's documentation is direct about this. "Not a headless CMS — EmDash is tightly integrated with Astro and runs in the same deployment, rather than as a separate service you call over an API." If you already have a Next.js codebase and want EmDash as a decoupled backend behind it, that's not the use case EmDash is built around. This is the honest version of how to do it anyway, and what it costs you.
Table of Contents
- What EmDash Actually Offers a Non-Astro Frontend
- What You Give Up Going This Route
- The Alternative Worth Considering First
- If You Still Want Next.js Specifically
- Frequently Asked Questions
- Is there an official EmDash Next.js SDK or adapter?
- Will content changes show up in Next.js immediately, like they do in Astro?
- Should I migrate my Next.js app to Astro instead?
- Does EmDash support GraphQL for non-Astro frontends?
- The Bottom Line
What EmDash Actually Offers a Non-Astro Frontend
EmDash exposes a REST API at `/_emdash/api/` for content, media, and schema operations, authenticated via Bearer token, with CORS support for browser requests (configurable allowed origins in your deployment). That means a separate Next.js application genuinely can fetch content from an EmDash instance — it's just not the integrated, single-deployment experience EmDash is designed around.
GET /_emdash/api/content/posts
Authorization: Bearer YOUR_API_TOKENA minimal fetch from a Next.js Server Component:
async function getPosts() {
const res = await fetch("https://your-emdash-site.com/_emdash/api/content/posts?status=published", {
headers: { Authorization: `Bearer ${process.env.EMDASH_API_TOKEN}` },
});
const json = await res.json();
return json.data.items;
}
export default async function BlogPage() {
const posts = await getPosts();
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.data.title}</li>
))}
</ul>
);
}What You Give Up Going This Route
EmDash's own comparison table is direct about the trade-off between its integrated model and a traditional decoupled headless setup:
Headless CMS: Frontend — bring your own. Deployment — CMS + frontend, separately. Content updates — webhook/rebuild. EmDash: Frontend — Astro components. Deployment — single deployment. Content updates — immediate (SSR).
Running EmDash behind a separate Next.js app puts you squarely in that "headless CMS" row, not the integrated one. Concretely, that means:
- No automatic live updates — Next.js won't know content changed until you rebuild, use ISR with a revalidation interval, or wire up an on-demand revalidation webhook yourself.
- No generated TypeScript types flowing from your content model into your templates — you're working with EmDash's generic REST response shape instead.
- Two deployments to manage and keep in sync (the EmDash/Astro instance and the Next.js app), instead of one.
- You still need to run EmDash's own Astro-based admin somewhere — this doesn't remove that piece, it just adds a second application in front of it.
The Alternative Worth Considering First
If the actual reason you want Next.js is React components — not Next.js's routing, data fetching, or specific framework features — Astro supports rendering React components directly inside an Astro-native EmDash site via the official `@astrojs/react` integration. This project's own `astro.config.mjs` uses exactly that pattern:
import react from "@astrojs/react";
export default defineConfig({
integrations: [
react(),
emdash({ /* ... */ }),
],
});With that integration in place, you write `.tsx` React components and drop them into `.astro` pages as islands — getting real React where you need interactivity, while EmDash's content queries, live updates, and generated types keep working exactly as documented. For most teams whose actual requirement is "I want to write React," this satisfies that without the deployment split and lost integration benefits of a separate Next.js app.
If You Still Want Next.js Specifically
- Deploy EmDash as its own Astro application (Node.js or Cloudflare Workers) — this is your content backend and admin panel.
- Generate an API token from the EmDash admin panel for your Next.js app to authenticate with.
- Configure CORS in your EmDash deployment to allow your Next.js app's origin.
- Fetch content in Next.js via the REST API — Server Components with `fetch`, or a data-fetching library of your choice.
- Handle content freshness yourself: ISR with a short revalidation window is the simplest approach; a `content:afterSave` plugin hook calling your Next.js revalidation webhook is the more precise one.
Frequently Asked Questions
Is there an official EmDash Next.js SDK or adapter?
No — EmDash's integration surface (query functions, generated types, live updates) is Astro-specific. A Next.js app talks to EmDash the same way it would talk to any REST API, with no framework-specific tooling provided.
Will content changes show up in Next.js immediately, like they do in Astro?
Not automatically. EmDash's "immediate at runtime" behavior is specific to Astro's Live Content Collections within the same deployment. A separate Next.js app needs its own revalidation strategy — ISR, on-demand revalidation, or polling.
Should I migrate my Next.js app to Astro instead?
If EmDash's specific benefits (single deployment, live updates, generated types) matter enough to your project, and you can render your interactive components as React islands within Astro via `@astrojs/react`, that's a more aligned path than bolting EmDash onto Next.js as a decoupled backend. If your Next.js app has deep framework-specific dependencies (App Router-specific patterns, Next-only libraries), that migration cost is real and worth weighing honestly.
Does EmDash support GraphQL for non-Astro frontends?
No — the documented API surface is REST, not GraphQL. If your Next.js app specifically expects a GraphQL API the way Contentful or Hygraph provide, EmDash doesn't offer that today.
The Bottom Line
EmDash is explicit that it isn't built to be a decoupled headless backend for a separate frontend framework — its REST API makes that technically possible, but you lose the live updates, type safety, and single-deployment simplicity that are EmDash's actual selling points. If your real need is React components, `@astrojs/react` inside a native EmDash site is very likely the better answer. See our full guide to connecting EmDash with Astro the way it's designed to work for that path.




Comments