xmcloud-edge-dev
v0.1.0
Published
Zero-Docker local development for Sitecore XM Cloud JSS Next.js apps — run against Experience Edge instead of a local CM container.
Maintainers
Readme
xmcloud-edge-dev
Zero-Docker local development for Sitecore XM Cloud JSS Next.js apps.
The problem
The documented way to run a Sitecore XM Cloud front end locally is to run the CM (Content Management) instance in a container — which on Windows means Windows containers. That's a dealbreaker for Mac and Linux developers, and friction for everyone else: a multi-GB image, a Windows-container-capable Docker installation, and a CM boot cycle just to render pages from content that already lives in XM Cloud.
There's a workaround that shows up in blog posts and internal wikis but has
never been packaged as a tool: skip local CM entirely and point your local
Next.js JSS app straight at the remote Experience Edge GraphQL endpoint
using SITECORE_EDGE_CONTEXT_ID. Content still comes from your real XM Cloud
environment; you just don't run a CM container to get it.
xmcloud-edge-dev turns that manual workaround into a maintained CLI:
| | Before | After |
|---|---|---|
| Requirements | Docker Desktop + Windows containers, dotnet, Sitecore CLI | Node.js only |
| Platform | Windows-only (Windows containers) | Windows, macOS, Linux |
| Startup | Pull/build CM image, wait for CM to boot | npm run dev against Edge, instant |
| Config | Manually edit .env, guess at variable names | xmcloud-edge-dev init — validated against a real Edge request |
| Diagnostics | Read container logs, dig through Docker network issues | xmcloud-edge-dev doctor — plain-English checks |
| Editing/personalization preview | Not available without a live CM + Pages | Lightweight dev-only visual overlay |
Install
npm i -D xmcloud-edge-devRequires Node.js >= 18.17. No Docker, no Sitecore CLI, no dotnet tooling.
Quick start
npx xmcloud-edge-dev initThis will:
- Detect an existing JSS Next.js project (
sitecore.config.js/jss.config.js/@sitecore-jss/sitecore-jss-nextjsinpackage.json). If none is found, it offers to scaffold one from the officialxmcloud-foundation-headstarter. - Prompt for
SITECORE_EDGE_CONTEXT_ID, site name, and an API key if your endpoint needs one. - Write
.env.localwith the Edge variables, commenting out (not silently deleting) any leftover CM-only variables likeSITECORE_API_HOSTthat no longer apply. - Make a real GraphQL request to Edge to confirm the context id resolves and the site name actually exists — a written file isn't treated as success.
Non-interactive / CI mode
npx xmcloud-edge-dev init \
--yes \
--context-id "$SITECORE_EDGE_CONTEXT_ID" \
--site-name my-siteCommands
init
xmcloud-edge-dev init [options]
-d, --dir <path> target project directory (default: cwd)
--env-file <name> env file to write (default: .env.local)
--context-id <id> SITECORE_EDGE_CONTEXT_ID
--edge-url <url> Edge Platform base URL override — not a real env var,
never persisted to .env.local; only affects this run's
own connectivity check (default: https://edge-platform.sitecorecloud.io)
--site-name <name> SITECORE_SITE_NAME
--api-key <key> SITECORE_API_KEY, only if your endpoint requires one
-y, --yes non-interactive; fails instead of prompting
--skip-validate write config without making a live Edge requestdoctor
xmcloud-edge-dev doctor [--dir <path>] [--env-file <name>] [--edge-url <url>]Checks, in order:
- Node version — fails if below the supported minimum.
- Required env vars —
SITECORE_EDGE_CONTEXT_ID/SITECORE_SITE_NAMEpresent. - Config shape — validated with the same
zodschemainituses. - Experience Edge connectivity — a real GraphQL request; distinguishes
"Edge unreachable" from "Edge reachable, but this site name doesn't exist
in this context," and will suggest the last site name that did validate
successfully for that context id (cached locally in
.xmcloud-edge-dev.cache.json) if the current one looks like a typo.
Exits non-zero on any failed check, so it's safe to use as a pipeline gate.
sync-env
xmcloud-edge-dev sync-env --environment-id <id> [--token <token>] [--write] [--yes]Fetches the variables configured on an XM Cloud environment (via the Sitecore
Cloud Deploy/Environment API — pass a token with --token or
SITECORE_CLOUD_API_TOKEN; the API base URL is overridable with --api-url
since this surface is still evolving, so double-check the path against
current Sitecore docs for your plan) and diffs it against .env.local:
- missing — defined remotely, absent locally
- stale — defined in both, different values
- extra — local-only, not in the remote environment
Every value in the report is masked to its last 4 characters — raw secrets
are never printed. Pass --write to append missing variables locally (prompts
for confirmation unless --yes). Exits non-zero when drift is found, for CI.
Mock editing & personalization overlay
Because there's no local CM, Pages/Experience Editor "edit mode" isn't
available when developing against Edge. xmcloud-edge-dev/dev-overlay ships a
small, dev-only React layer that simulates it visually:
import { EditableFieldMarker } from 'xmcloud-edge-dev/dev-overlay';
<EditableFieldMarker fieldName="Heading">
<h1>{fields.heading.value}</h1>
</EditableFieldMarker>;Hovering the wrapped field outlines it and shows its field name — a visual, non-persistent stand-in for where a real Experience Editor click target would be. No auth, no CM round-trip, nothing to click through to.
For personalization, wrap a component with withMockPersonalization and
render PersonalizationProvider once near your app root:
import { PersonalizationProvider, withMockPersonalization } from 'xmcloud-edge-dev/dev-overlay';
const Hero = withMockPersonalization(DefaultHero, [
{ variantId: 'variant-a', render: (props) => <DefaultHero {...props} title="Variant A" /> },
{ variantId: 'variant-b', render: (props) => <DefaultHero {...props} title="Variant B" /> },
]);
// near the root of your app:
<PersonalizationProvider>
<App />
</PersonalizationProvider>;A floating "Personalize" toggle appears in the corner of the browser, letting you switch between registered variant ids and preview rendering without any real personalization configured in CM.
Production-safe by construction: every export in dev-overlay checks
process.env.NODE_ENV !== 'production' and returns the untouched
children/component when it's not development — this is a dev dependency
(npm i -D), and the overlay never activates in a production build.
What this tool does not do
- It does not replicate CM authoring — this is a front-end/headless dev velocity tool, not a CM clone.
- It never stores or proxies real Sitecore credentials outside your local
.env.local(or your OS keychain, if you choose to source values from there). Nothing is sent anywhere except the Edge/Cloud API endpoints you configure. - It doesn't assume a hosting target — it's just Node, so it runs the same on Vercel, Netlify, or your own infrastructure.
Development
npm install
npm run build # tsup -> dist/
npm run typecheck
npm test # vitest: unit + integration (mock HTTP server, no real tenant)