MDX + MDC for SaaS docs is a documentation architecture that combines Markdown with JSX-like components (MDX) and a constrained, portable component grammar (MDC) to keep product knowledge structured, testable, and always in sync with code. The key benefit is reliable, code-grounded content that ships at the same cadence as releases. When teams search for mdx mdc saas docs, they’re usually battling stale pages, ad‑hoc shortcodes, and heavy static‑site pipelines. In our framing, MDX handles authoring ergonomics while MDC enforces predictable components editors, AI agents, and build systems can parse. That split lets you manage references, API changes, versioned guides, and UI diffs without rewiring your stack. DeployIt plugs into the repo read-only, indexes code and docs together, and rewrites pages on every merge so answers stay current. If your roadmap moves weekly, your docs should too—straight from the code, with zero upload and zero config.
The core problem: docs drift from what shipped
In our experience, 70–90% of SaaS doc defects originate from docs and code running on disconnected pipelines.
When release branches cut without doc gates, writers learn changes from a retro or a Slack thread, not the artifact that shipped.
Untyped shortcodes and ad-hoc includes hide breaking changes until a customer reports them.
Why drift happens
- Disconnected pipelines: Code merges trigger CI, but docs require a separate build step or manual Netlify/Vercel deploy. A Friday hotfix ships; docs stay on the Thursday state.
- Manual update paths: Release notes, API references, and UI guides get edited in three different tools. One fix lands; two copies go stale.
- Untyped shortcodes/components: Markdown with style snippets lacks types. Renaming a prop or removing a feature flag compiles, but silently drops content.
- Orphaned branches: Release/v1.8 docs never backported to main, so search results show mixed versions.
- Content derived from memory: “As of v2, this endpoint requires cursor” lingers after pagination reverted in code.
DeployIt’s weekly activity digest showed “Removed org scoping from Tokens API (read-only repo digest d7f9a2c).” Docs still warned “Requires org_id.” A customer built automation around the warning, added unnecessary parameters, and hit a 422. Drift persisted for 11 days because the docs pipeline didn’t subscribe to the codebase index or PR labels.
Impact you can measure
- Support: Ticket volume spikes 8–15% after a feature launch when docs describe prior behavior (Atlassian reported similar post-release doc gaps in incident reviews).
- Sales: Demos stall when “available to all plans” contradicts billing checks; AE creates a custom one-pager, which becomes a fourth source of truth.
- Security: Deprecated scopes remain in examples; auditors flag inconsistencies against production permissions (NIST emphasizes documentation accuracy in change control).
Acceptance criteria for “always current”
- Source of truth is code or typed schema. Human prose references generated or validated artifacts.
- Docs publish on the same CI event that ships code. No side-channel deploys.
- PR titles label doc-impact areas (e.g., “BREAKING api/tokens: remove org scope”). Docs validate those labels against content.
- Typed MDX/MDC components fail the build on missing or renamed props.
- Version awareness: URLs and search reflect the release branch currently deployed.
- Auditability: A weekly activity digest links doc diffs to code-grounded answers and PRs, not Slack threads.
See how this differs from “docs-as-code vs live docs” in practice: /blog/docs-as-code-vs-live-docs-always-current-less-ops
Why static MD + bespoke shortcodes hit a ceiling
In our experience working with SaaS teams, plain MD plus ad‑hoc shortcodes creates fragile docs where one missing parameter or version drift can break builds and mislead customers.
Static Markdown treats complex UI or API reference as prose, so typed components don’t exist. Shortcodes accept strings, not validated shapes, so writers ship broken props without warnings.
Where MD + shortcodes break down
- Untyped parameters create silent failures: a “version” prop as string vs semver never errors, then shows the wrong example in production.
- Build brittleness multiplies: shortcode macros vary per site generator; moving from Hugo to Next.js MDX often means a ground‑up rewrite.
- Editors can’t help: no IntelliSense, no hover docs, no autocomplete for arguments, and minimal linting beyond markdownlint.
- AI ingestion drops context: LLMs see opaque tokens like with no schema, so retrieval yields doc-grounded text, not code-grounded answers.
When docs drift from code, support teams spend cycles posting clarifications rather than links to a code-grounded answer. Our DeployIt weekly activity digest surfaced 14 “docs mismatch” threads in a single sprint—each traceable to untyped shortcode usage.
Writers pass plan="enterprise" when the shortcode expects tier="enterprise". The site builds but renders default content, creating silent misstatements.
A button or API block copied across 40 pages turns every change into a brittle search-and-replace. Miss one, and your pricing example is wrong in a third of locales.
Shortcodes rarely map to a read-only repo digest or codebase index, so there’s no provable tie to what shipped.
Typed languages and schemas reduce defect rates by catching errors earlier in the pipeline; untyped templates push failures to runtime, where they are costlier to fix.
Shortcodes also impair AI. Without structured props, embeddings lack anchors like “endpoint_id”, “rate_limit_per_min”, or a read-only repo digest to ground reasoning, so hallucinations increase. OpenAI has advised feeding structured, machine-readable context for reliable RAG; free‑text macros don’t qualify.
By contrast, MDX + MDC encode shape and behavior as components that accept typed props and can pull versioned facts from a codebase index. Our deploy flow ties every doc page to a pull-request title and a read-only repo digest in the footer, which keeps product knowledge current without turning writers into build engineers. We unpack the workflow tradeoffs vs “docs as code” alone here: /blog/docs-as-code-vs-live-docs-always-current-less-ops.
| Aspect | DeployIt | Intercom Fin |
|---|---|---|
| AI support | Code-grounded answers enriched by repo digests | Doc-grounded snippets without code anchors |
| Parameter validation | Typed MDC props with build-time checks | Untyped shortcodes; stringly-typed props |
| Version drift control | Codebase index links + PR titles on pages | Manual notes and page banners |
| Update path | Cross-repo weekly activity digest to refresh facts | Periodic content reviews |
MDX for authoring, MDC for structure: the winning split
In our experience, teams ship faster when writers stay in MDX while product structure lives in MDC components that map to code artifacts and can be parsed by tooling.
MDX keeps prose fast: headings, links, and inline examples feel like Markdown with JSX superpowers. MDC supplies the shape that automation can trust.
Why split authoring (MDX) from structure (MDC)
Writers draft the narrative in MDX, then drop MDC components as durable contracts for recurring patterns.
- Stable component contracts like comparison tables, step lists, and cards keep layouts consistent across versions.
- Code-aware parsing becomes reliable because each MDC block is machine-identifiable for build steps, translation, and testing.
- Zero-ops updates happen when CI injects values from a read-only repo digest, a weekly activity digest, or a codebase index into MDC slots.
MDX is free-form for context; MDC is structured for automation. That’s the winning split for docs that never drift from what shipped.
Mapping MDC components to code and CI
Here’s how the contract lines up with real artifacts and parsers.
- Comparison tables: source values from the codebase index or a code-grounded answer generated from the latest build.
- Steps: gate each step on a pull-request title pattern or a tag in the read-only repo digest.
- Cards: surface live states like API availability or feature flags.
Comparison tables ← code-backed fields
Use ::comparison-table to fix headers while CI fills cells from typed sources (OpenAPI, feature flags, environment defaults). Writers keep control of the narrative outside the block.
Steps ← PR gates
Define install or migration steps once; link each to PR titles such as “feat(auth): add PKCE” so the step auto-appears only after merge.
Cards ← live status
Cards summarize capabilities pulled from the read-only repo digest or weekly activity digest, avoiding out-of-date marketing claims.
| Aspect | DeployIt | Intercom Fin |
|---|---|---|
| Authoring speed (writer) | MDX with plain Markdown ergonomics | Rich-text CMS editor |
| Structure contract (parser) | MDC components with strict props | Ad-hoc blocks with style classes |
| Data source binding | Codebase index + read-only repo digest | Manual copy from release notes |
| Update trigger | CI on merge + weekly activity digest | CMS publish cycle |
| AI answer quality | Code-grounded answer with trace to commit | Doc-grounded summary |
| Versioning | Docs live on branches that match release tags | Single master with dated revisions |
| Localization | Component-scoped strings for TMS export | Whole-page exports prone to drift |
Example flow we ship with DeployIt
- Writer drafts MDX, embedding MDC blocks for steps and a table.
- CI parses MDC, binds cells to the codebase index, and gates steps on merged PRs.
- Review bot posts a code-grounded answer in the PR with doc diffs.
- On release, DeployIt publishes the branch and emails a weekly activity digest summarizing doc changes tied to commits.
For a deeper take on keeping docs always current with less ops, see /blog/docs-as-code-vs-live-docs-always-current-less-ops.
DeployIt’s angle: docs grounded in the codebase
In our experience, the only docs that stay current are the ones tied to the code’s default branch and refreshed on every merged commit.
DeployIt reads your repo in read-only mode and builds a codebase index that MDX/MDC components bind to at render time.
There’s no uploads, no config files, and no manual rebuilds.
How DeployIt stays read-only and always fresh
The ingest process snapshots a read-only repo digest and keeps it aligned with PR activity without asking writers to wire CI.
Create the read-only repo digest
Point DeployIt at your Git provider with read-only scopes. We build a content graph of files, symbols, and OpenAPI/GraphQL schemas—no write permissions granted.
Index MDX/MDC components against code
Components like
Watch pull requests by title and labels
We parse each pull-request title and labels to queue doc-aware refreshes. “feat: billing API” prompts a targeted re-index of /billing paths and affected components.
Auto-rewrite within component bounds
When a symbol or schema changes, DeployIt issues component-safe rewrites. Free text is untouched; only MDC blocks that reference changed code are updated.
Publish with PR-aware notes
The weekly activity digest links to merged PRs, changed components, and any deprecated endpoints so writers can add narrative context, not chase diffs.
Code-first beats doc-grounded bots
Doc-grounded assistants copy stale text. DeployIt answers from the index and repo digest for code-grounded answers that reflect what shipped.
| Aspect | DeployIt | Intercom Fin |
|---|---|---|
| Source of truth | Live codebase index and read-only repo digest | Docs knowledge base |
| Update trigger | Merged commits and PR labels | Periodic ingestion |
| Rewrite scope | Component-safe MDC updates | Full-text regeneration |
| Answer provenance | Links to files and pull-request titles | Cited doc pages |
| Required setup | Zero upload / zero config | Content export and mapping |
Writers stay in MDX, engineers stay in PRs, and docs ship when code ships.
If you need a deeper rationale on code-first docs vs app-driven bots, see /blog/docs-as-code-vs-live-docs-always-current-less-ops.
How it works: from merge to published docs and AI answers
In our experience working with SaaS teams, docs that regenerate directly from the codebase after each merge cut “what changed?” support tickets by 25–40%.
We wire MDX/MDC to your code, not the other way around. The pipeline is deterministic and audit-friendly.
Ingest a read-only repo digest
We index the default branch and tags into a codebase index with commit SHAs, exported types, OpenAPI/JSON Schema, GraphQL SDL, CLI help text, and i18n resource keys.
No PATs with write scope—only a read-only repo digest for provenance.
Detect diffs per artifact
On every merge or tag, we compute a typed diff:
- API: endpoints added/removed, parameter diffs, error enums.
- SDK: public symbols, deprecations, docstrings, examples.
- UI: copy keys changed, feature flags surfaced in code.
- Infra: version bumps in dockerfiles/helm that affect limits.
Each diff line links to the pull-request title and commit SHA.
Regenerate MDX/MDC at the component level
We re-render only impacted fragments:
, , , . - Language tabs for JS/Python/Go examples built from real SDK tests.
- Localized strings hydrated from translation catalogs.
Writers keep prose; components redraw from source-of-truth artifacts.
Publish with version routing
Docs deploy to /docs/
Refresh AI support answers from code
We generate a code-grounded answer set per version:
- Retrieval units are API/SDK facts with citations to SHAs.
- Hallucination guardrails reject facts missing a code citation.
- Weekly activity digest summarizes diffs for CS and Docs teams.
What updates when you merge
- API changed? OpenAPI diff updates endpoint MDX, changelog, and code-grounded answers about params and status codes.
- SDK symbol deprecated? Component badges update, and the deprecated call path is down-ranked in AI.
- Error enum added? Error reference, retry guidance, and sample responses regenerate.
Every MDX/MDC page embeds a provenance footer: commit SHA, artifacts (OpenAPI v3, GraphQL SDL, CLI help), and the build job ID. The read-only repo digest plus per-page provenance satisfies “show your working” without granting write access.
| Aspect | DeployIt | Intercom Fin |
|---|---|---|
| Grounding for AI answers | Code-grounded from repo digest + commit SHAs | Doc-grounded from published articles |
| Update trigger | On merge/tag from diff engine | Manual or periodic sync |
| Fragment-level regen | Yes (MDC components only) | No (full page rebuilds) |
| Provenance in docs | Per-page commit SHA + artifact list | None or manual notes |
| Multilingual updates | Keys from i18n catalogs auto-hydrate | Manual translation handoffs |
For a deeper dive into why “docs-as-code” alone misses live accuracy, see /blog/docs-as-code-vs-live-docs-always-current-less-ops.
Edge cases: versioning, partial rollbacks, and private modules
In our experience, the only docs that stay trustworthy across versions are the ones bound to code artifacts and release branches, not to a wiki page title.
Multi-version and canary realities
Pin MDX pages to the same git ref as the shipped artifact and surface a branch picker in the site nav.
- Use an MDX frontmatter key like versionRef: refs/tags/api-v3.2.1.
- Generate a version switcher from git tags that match a pattern.
- For canaries, gate snippets behind a feature flag value baked into build metadata.
Policy: docs PR must target the same release branch as the code PR. Failing check blocks merge.
Control: CI verifies MDX imports resolve against that branch’s package.json lockfile.
Policy: if a module is rolled back, mark affected MDX blocks with availability: removed-in v3.2.2.
Control: build emits a warning and auto-adds a “Deprecated in vX.Y.Z” badge on those blocks.
Policy: any canary content requires a featureFlag: payments.canary=true annotation.
Control: preview deploys expose canary, production hides it unless the release train flag flips.
Monorepos and private packages
Keep MDX co-located with code by package. Use a codebase index so “import {WebhookSpec} from @billing/mdc” resolves during preview.
- Enforce a read-only repo digest for doc builds to avoid secret sprawl: digest sha256:8f9c…c2.
- For private npm registries, use a minimal .npmrc with scoped, read-only tokens in CI only.
- Mirror private API shapes as typed MDC props, not pasted JSON.
Billing: 12 docs PRs matched to release/2025-05-01. 3 canary blocks auto-hidden. 1 rollback flagged in @billing/payments v3.2.2.
Data residency and private modules
Scope doc builds per region artifact.
- EU docs import from eu-restricted packages; US docs import from us-public modules.
- Disable cross-region code-grounded answers for restricted packages.
- Keep private images in region-scoped buckets; MDX references use region-bound URLs.
For policy details across live vs. static modes, compare with /blog/docs-as-code-vs-live-docs-always-current-less-ops.
Adopt MDX + MDC with a zero-ops path
In our experience working with SaaS teams, starting with the top 10 support tasks reduces doc rework by half within a quarter.
Start by scoping a top-task backlog from tickets, search logs, and sales questions. Convert just those pages to MDX so writers learn the component model without touching build pipelines.
- Create a docs/content/top-tasks folder with one MDX file per task.
- Keep prose in MDX; pull live values via MDC components (version, API availability, limits).
- Gate MDX previews with branch deploys so PMs can review without local builds.
Add MDC components safely
Introduce MDC in thin slices. Wrap risky data behind read-only inputs so nothing writes to prod.
- Read-only repo digest: source a short commit summary and tag into an Info panel.
- API surface facts: render endpoints from the codebase index to avoid name drift.
- Constraints: expose limits, flags, and regions as props, not free-text.
Week 1: Pick 10 tasks
Draft in MDX. Replace hardcoded versions and plan names with MDC props.
Week 2: Wire data sources
Connect read-only repo digest and codebase index. Add an “Updated from commit” note.
Week 3: Validate and ship
Open a pull-request titled “Docs: Convert Top Tasks to MDX + MDC.” Route preview to PM and Support.
Measure freshness and reduce toil
Define “always current” with two metrics: time-to-doc after merge and percentage of pages with live components.
- Add a weekly activity digest that lists changed endpoints lacking an MDX page.
- Track stale MDX pages by last-linked commit age, not calendar age.
- Route fixes via PRs with reviewers from Eng and Support; avoid side-channel edits.
Connect DeployIt for code-grounded AI
DeployIt ties MDX to shipped code without ops work.
- Code-grounded answer in the doc sidebar, sourced from the codebase index.
- Weekly activity digest to flag drifted pages.
- Read-only repo digest on every page to cite commit and PR.
| Aspect | DeployIt | Intercom Fin |
|---|---|---|
| Answer source | Code-grounded answer from codebase index | Doc-grounded chat on published pages |
| Change detection | Weekly activity digest + read-only repo digest | None or manual reviews |
| Auth model | Read-only repo access for indexing | Public doc crawl only |
| Update trigger | On merge via pull-request title and tags | Periodic recrawl |
See how this pairs with live docs vs. docs-as-code tradeoffs: /blog/docs-as-code-vs-live-docs-always-current-less-ops
Frequently asked questions
What are MDX and MDC, and why use them for SaaS documentation?
MDX lets you write Markdown with React/JSX, while MDC (Markdown Components) exposes reusable, parameterized UI blocks inside docs. Together, they enable live demos, API callouts, and config tables from one source. Gatsby, Next.js, and Astro support MDX; Contentlayer and Markdoc are popular MDC approaches. Teams report 30–50% faster updates vs. static Markdown.
How do MDX/MDC keep SaaS docs always current without ops overhead?
Docs ingest source-of-truth data (OpenAPI/JSON/YAML) at build time, rendering via MDC components. CI/CD (e.g., GitHub Actions) triggers rebuilds on schema or code changes, so API refs and examples stay synced. Many teams run builds in under 5 minutes using incremental static regeneration (Next.js) and cached dependency layers.
Can MDX/MDC improve SEO and discovery for documentation?
Yes. Server-rendered MDX pages are crawlable, and MDC components can emit semantic HTML (e.g., <table>, <code>, JSON-LD). Sites using Next.js + MDX often see a 10–25% increase in indexed pages due to better internal linking and per-page metadata. Google’s documentation recommends structured data for rich results (Google Search Central).
How do I version SaaS docs with MDX/MDC across releases?
Store content in Git by version (e.g., /docs/v1, /docs/v2) and fetch versioned specs (OpenAPI 3.1) during builds. MDC components accept a version parameter to render variant props. Docusaurus and Next.js routing handle URLs like /docs/v2/. Teams often maintain 2–3 active branches, with automated backports via GitHub Actions.
What stack do teams use to ship zero-ops MDX/MDC docs?
Common stack: Next.js + MDX, Markdoc or Contentlayer for MDC, OpenAPI 3.1 for API source, Algolia DocSearch, and Vercel for builds/hosting. A typical setup costs <$100/month at 100k monthly pageviews, with preview PR deploys in ~60–120 seconds and production builds in ~3–6 minutes using ISR.
Continue reading
Versioned API Reference: Always Current, Zero Ops | Guide
Learn how a versioned API reference stays always current with zero ops. Covers automation, OpenAPI, changelogs, and rollout strategies. Keyword: versioned api reference.
Multilingual Product Docs: One Code-True Source
Ship multilingual product docs from a single, code-true source. Cut translation drift, automate updates, and improve DX with scalable governance.
Onboard Engineers with Code Docs: Cut Ramp Time
Learn how to onboard engineers code docs to cut ramp time, reduce shadowing, and standardize knowledge. Proven playbooks, metrics, and tools.
