Skip to main content
Wire MDCMS into a real application you own. This guide covers host app responsibilities, Studio embedding, authentication, and production configuration.
Need a running server first? See Self-Hosting. Need to install the CLI and define your schema? See the Quick Start.

Prerequisites

Before integrating, you need:
  1. A running MDCMS server — self-hosted via Docker Compose or a managed instance
  2. The CLI installed and a project initializednpx mdcms init creates your mdcms.config.ts and syncs your schema
  3. A React application — Next.js App Router is the primary example below; any React framework with catch-all routing works

Host app responsibilities

MDCMS handles content storage, the Studio UI, authentication flows, and the API. Your host app provides the mount point and configuration.

Installing packages

Install @mdcms/studio to embed the visual editor. Add @mdcms/sdk if you also query content for rendering.

Project configuration

Your mdcms.config.ts (created by mdcms init) drives both CLI sync and Studio embedding. The fields that matter for integration:
mdcms.config.ts
See the Schema Guide for field types, references, and environment overlays.

Live preview routes

Real-app live preview is configured per content type in mdcms.config.ts. Keep route mapping with the model definition so Studio, the CLI, and host app code agree on where a document should render.
mdcms.config.ts
When Studio opens a preview pane it:
  1. resolves the preview URL from the persisted draft snapshot;
  2. asks the MDCMS server for a short-lived preview token;
  3. appends that token as mdcms_preview_token;
  4. loads the tokenized URL in the iframe;
  5. waits for the framed route to post { type: "mdcms:live-preview-ready" }.
Send the ready message from client-side code after the preview page has rendered:
Private preview routes should verify the token before fetching drafts:
preview=true can be useful as a readable mode flag, but it is not proof that the caller may read private drafts. If your deployment intentionally makes drafts public, document that decision and still avoid reusing static published-page caches for preview responses.

Embedding Studio

Studio is a React component that owns all rendering under a catch-all route (e.g., /admin/*). The recommended pattern splits server and client concerns so the config can be safely serialized across the boundary.

Basic setup

Use this when you do not register custom MDX components.
1

Create the server component

The server component imports your config, strips non-serializable values via createStudioEmbedConfig, and passes the result to the client component.
app/admin/[[...path]]/page.tsx
2

Create the client component

The client component renders Studio. The basePath prop tells Studio which URL prefix it owns.
app/admin/[[...path]]/admin-studio-client.tsx
basePath is required. Studio cannot infer its mount prefix from deep links like /admin/content/posts/abc. Set it to the path prefix your catch-all route uses.
Other React frameworks: The pattern is the same for any framework — create a catch-all route that renders the <Studio> component. In Remix, use a splat route (admin.$.tsx). In Vite with React Router, use a wildcard route (/admin/*). The key requirement is that Studio receives all sub-paths under its mount point.

Setup with MDX components

If your app registers custom MDX components for the Studio editor (e.g., <Chart>, <Callout>, <PricingTable>), use prepareStudioConfig on the server to extract TypeScript prop metadata at build time.
1

Register components in your config

Add component registrations to your mdcms.config.ts. Each component needs a name, importPath, and a load function. Optional: propHints for widget customization, propsEditor/loadPropsEditor for fully custom prop editing UI.
mdcms.config.ts
2

Prepare config on the server

prepareStudioConfig reads your component source files and extracts TypeScript prop types so the Studio editor can generate form controls automatically.
app/admin/[[...path]]/page.tsx
3

Build the client config

The client component merges extracted prop metadata back onto the component registrations (which include the runtime load callbacks).
app/admin/[[...path]]/admin-studio-client.tsx
prepareStudioConfig reads your TypeScript source files at build time. It requires cwd pointing to your project root and tsconfigPath to your tsconfig.json. If your components are in a separate package, adjust these paths accordingly.

Authentication and CORS

Studio communicates directly with the MDCMS server API. Authentication determines how Studio identifies the current user.

Studio props reference

Fetching content with the SDK

If your app renders MDCMS content (blog posts, pages, etc.), use @mdcms/sdk to query the API:
See the SDK reference for filtering, pagination, error handling, and Next.js patterns.

Production checklist

Before going live, verify each item:
  1. HTTPS everywhere — both the MDCMS server and your host app serve over HTTPS
  2. Secure cookiesMDCMS_AUTH_INSECURE_COOKIES is removed or set to false
  3. CORS locked downMDCMS_STUDIO_ALLOWED_ORIGINS lists only your production origin, not localhost
  4. Production modeNODE_ENV=production on the MDCMS server
  5. Strong credentials — database, S3, and Redis credentials are unique and not defaults
  6. API keys scoped — keys are scoped to the minimum required permissions and rotated periodically
  7. Real email provider — SMTP is configured with a production provider, not Mailhog
See the Self-Hosting guide for detailed server-side production hardening.

Next steps

Studio Guide

Dashboard overview, navigation, and all Studio features

Schema Guide

Field types, references, environment overlays, and MDX components

CLI Commands

Push, pull, login, schema sync, and all CLI flags

SDK Reference

Full typed client API for content reads