Dev Server

Run sitemd launch to start a local dev server at localhost:4747. Every feature works — pages, auth, forms, data, analytics, SEO, gating — regardless of activation status. Save any file and the site rebuilds automatically.

How it works

The dev server renders your site in memory and serves it as a single-page application. Instead of writing HTML files to disk, it builds all pages into an in-memory store and serves them through a lightweight HTTP server with SPA navigation.

Browser request → skeleton HTML shell
  └─ hydrate.js fetches shell (header, footer) from /__api/shell
  └─ hydrate.js fetches page content from /__api/page?slug=/about
  └─ hydrate.js fetches metadata from /__api/meta?slug=/about
  └─ clicking a link → fetches the new page without a full reload

The skeleton HTML is an empty document with container elements. All content is loaded client-side by the hydration script. View-sourcing a page shows references to localhost URLs — without the dev server running, the page is blank.

Skeleton HTML

Every page request returns the same HTML shell:

<div id="sitemd-shell"></div>      <!-- header + nav injected here -->
<main id="sitemd-main">
  <article class="content"></article>  <!-- page content injected here -->
</main>
<div id="sitemd-footer"></div>     <!-- footer injected here -->

The hydration script (hydrate.js) populates these containers by calling the dev server API. Navigation between pages swaps the content without reloading — page transitions are instant.

API endpoints

The dev server exposes internal endpoints for the hydration layer:

Endpoint Returns
/__api/shell Header HTML, footer HTML, brand, theme CSS path
/__api/page?slug=/about Rendered page content (the <article> inner HTML)
/__api/meta?slug=/about Page title, description, sidebar, nav, auth attributes
/__api/layout-scripts Inline JS from theme/layout.html (search, lightbox, modals)
/__reload Server-Sent Events stream for live reload

These endpoints are internal to the dev server. They don't exist in production builds.

Auth and data in dev mode

When an auth provider is configured in settings/auth.md, the dev server injects:

When a data provider is configured in settings/data.md, the dev server injects the data.js runtime script with provider credentials.

Auth and data work identically in dev and production. The only difference is where the HTML comes from — memory (dev) vs disk (production build).

Local auth testing

When using provider: custom, the dev server includes a built-in auth stub so you can test login, signup, magic links, gated pages, and account dashboards without a real API backend.

The stub intercepts all auth API calls locally — no external server needed. It accepts any email and password, exchanges any magic link code, and returns mock session data. Page gating, the header auth button, and gated sections all work exactly as they would in production.

How it works

The dev server overrides apiUrl to point to a local endpoint (/__auth) and handles all auth routes in-memory:

Action What happens
Login (any email + password) Creates a session, logs you in
Signup (any email + password) Creates a session, logs you in
Magic link exchange (any code) Creates a session, logs you in
Logout Clears the session
Account endpoints Returns mock user data from the current session
Licenses, activations, API keys Returns mock data

Sessions are stored in memory on the dev server. Restarting the server clears all sessions.

Navigate directly to your afterLogin page with any magic code in the URL hash:

http://localhost:4747/account#magic=anytoken

The stub accepts any value as a valid exchange code. You're logged in immediately.

Testing page gating

  1. Set auth: required in a page's frontmatter
  2. Visit the page while logged out — you're redirected to /login
  3. Log in with any email and password
  4. Visit the gated page again — content is visible

Testing gated sections

Add gated: blocks in your page content. Log in to see them appear. Log out to confirm they're hidden.

What the stub does not do

The stub is for testing UI flows. It does not:

For production auth behavior, configure your real API URL in settings/auth.md and deploy.

Third-party providers

The local auth stub only applies to provider: custom. If you use Supabase, Firebase, Clerk, or Auth0, the dev server connects to your provider directly — those providers handle auth in both dev and production.

What you see vs what ships

The dev server shows you the exact same site that sitemd deploy produces. The differences are structural, not visual:

Dev server Production build
HTML source Skeleton + client hydration Standalone, fully rendered
Output location Memory only site/ directory on disk
Navigation SPA (no full reloads) Standard page loads
SEO metadata Rendered in memory Written to HTML, sitemap.xml, robots.txt
Search Uses search index from last build Fresh search-index.json in output
Dev panel Available (⌘/) Not included
Trial banner Shown if not activated Not included

Trial vs activated

The dev server behaves the same whether the site is activated or not. All features render fully in both modes.

The only visible differences in trial mode:

These are licensing markers, not feature restrictions. Activate your site to unlock production builds. See Activate a Site.

Why skeleton HTML?

The dev server never writes standalone HTML to disk during development. This is by design:

Production-ready HTML is produced by sitemd build or sitemd deploy, both of which require activation.

Starting the dev server

Three ways to start:

# CLI
sitemd launch

# Agent skill
/launch

# MCP tool
sitemd_build   # with serve mode

The dev server watches pages/, settings/, and theme/ for changes. Saves trigger a rebuild and the browser refreshes automatically via Live Build Sync.