Documentation site for Magistrala, built with Fumadocs and Next.js.
Visiting /docs/magistrala/ redirects to /docs/magistrala/user-guide/architecture/.
pnpm dev # Enterprise Edition — http://localhost:3000/docs/magistrala/
pnpm dev:community # Community Edition — http://localhost:3001/docs/magistrala/community/Run both at once, in separate terminals, to check edition-gated content side by side. Each next dev process only serves one edition (its basePath/NEXT_PUBLIC_EDITION are baked in at startup — see Environment Variables), so the Edition switcher can't navigate correctly between two different dev ports; visit each URL directly instead. To test the real merged deployment, including the switcher, run pnpm run build && pnpm start and visit both editions on the same port (see Deployment).
latest ships as two editions from one deployment:
- Enterprise Edition — full feature set, served at the root path (
/docs/magistrala/) - Community Edition — Reports, Alarms, Rules Engine, and Dashboards docs excluded, served nested at
/docs/magistrala/community/
content/docs is a single shared tree. Pages/folders flagged enterprise: true (folder-level via meta.json, page-level via frontmatter — see source.config.ts) are filtered out of the Community build only, in lib/source.tsx. The sidebar's Edition switcher (components/edition-switcher.tsx) lets readers flip between the two; it only renders on latest, since v0.30.0 predates the edition split and is unaffected — it keeps its own single-pass build on its own branch/Worker.
This site uses:
- Next.js static export —
next buildoutputs static files toout/ - Next.js
basePath— generates links and assets under/docs/magistrala(Enterprise) or/docs/magistrala/community(Community), driven byNEXT_PUBLIC_BASE_PATH - Post-build nesting —
scripts/nest-static-export.mjsmoves each pass's export under its base path so Cloudflare static assets can serve it from the route prefix without custom Worker code - Edition build orchestration —
scripts/build-editions.mjsrunsnext buildtwice (once per edition, with different env vars) and merges Community's nested output as acommunity/subfolder inside Enterprise's tree — no second Worker or Cloudflare project needed, since/docs/magistrala/community/*is just a sub-path of the/docs/magistrala/*route the Worker already serves
| Setting | Value |
|---|---|
| Build command | pnpm run build |
| Deploy command | npx wrangler deploy |
| Version command | npx wrangler versions upload |
| Root directory | / |
flowchart LR
subgraph Build_and_Deploy
A[Git push] --> B[Cloudflare build trigger]
B --> C[pnpm run build]
C --> D1[next build — Enterprise pass]
D1 --> E1[nest export under out/docs/magistrala]
C --> D2[next build — Community pass]
D2 --> E2[nest export under out/docs/magistrala/community]
E1 --> M[merge Community into Enterprise out/]
E2 --> M
B --> F[npx wrangler deploy]
M --> G[Cloudflare static assets]
F --> G
end
subgraph Runtime_Request_Flow
U[Browser request] --> H[Cloudflare static asset route]
H --> J[Static asset lookup]
J --> U
end
scripts/build-editions.mjs sets these per build pass, so no Cloudflare dashboard configuration is required:
NEXT_PUBLIC_EDITION=enterprise|community
NEXT_PUBLIC_BASE_PATH=/docs/magistrala[/community]
NEXT_PUBLIC_BASE_URL=https://absmach.eu/docs/magistrala[/community]Defaults (when unset, e.g. running next build directly) match the Enterprise pass.
| Path | Description |
|---|---|
app/[[...slug]] |
Documentation pages and root redirect |
app/api/search/route.ts |
Static search index route handler |
app/og/[...slug] |
OG image generation for docs pages |
app/llms-full.txt |
LLM-readable full docs text |
content/docs |
MDX source files |
lib/source.ts |
Fumadocs source adapter — also filters Enterprise-only content out of the Community build |
lib/edition.ts |
Edition switcher data + CURRENT_EDITION (env-driven) |
lib/layout.shared.tsx |
Shared layout options |
scripts/nest-static-export.mjs |
Moves one build pass's static export under its base path |
scripts/build-editions.mjs |
Runs both edition builds and merges them into one out/ |
workers/image-proxy.ts |
Worker serving /docs/magistrala/{img,diagrams,screenshots}/* from R2 — see scripts/README.md |
scripts/publish-image.mjs |
Maintainer-only CLI to upload an image to R2 and purge its cache entry |
lib/remark-doc-images.ts |
Remark plugin resolving markdown image paths (relative or /screenshots/...) to their R2-proxy URL at build time |
All doc images (content/docs/img, content/docs/diagrams, public/screenshots) are
served from R2, not committed to git. Authoring is unchanged — write plain markdown
image syntax exactly as before (, ,
relative paths and all); lib/remark-doc-images.ts resolves
the path to its R2-proxy URL at build time (pure path math, no manifest, nothing to fill
in), and mdx-components.tsx's img: override renders it as a plain, zoomable <img>.
New or updated images go through scripts/publish-image.mjs — see
that doc for setup and usage.