Skip to content

Templates

MDX authoring guide

Minimal, end-to-end reference for writing new MDX documentation pages in the Datamotive docs system — frontmatter, file rules, components, workflow, and a copy-paste page template.

Product
Datamotive Platform
Version
v2.0.3
Documentation status
Draft
Last updated
Updated
Reading time
7 min read

This guide is the short, practical reference for writing any docs page in src/content/docs/. Pair it with the MDX component placeholders page when you need ready-to-paste snippets for each component.


Part 1 — What MDX gives you

MDX is Markdown plus React components. You write prose as normal Markdown, and where you need a callout, a tab group, a step list, or a table with badges you drop a component in directly:

mdx
This is a normal paragraph with **bold** and `code`.
 
<Callout type="warning" title="Watch out">
  Components live right next to your prose. No imports needed.
</Callout>

Every component in this repo is globally registered — you never write import statements in an MDX file.

When to use .mdx vs .md:

  • .mdx — every page under src/content/docs/
  • .md — repo-level files only (README.md, CHANGELOG.md, .github/ templates)

Part 2 — File layout

Pages live under src/content/docs/, organised by product or section:

text
src/content/docs/
  _templates/           ← internal authoring references (this guide lives here)
  getting-started/      ← onboarding
  core/                 ← platform concepts shared across products
  dr/                   ← Disaster Recovery
  migrate/              ← Migration
  protect/              ← Protection
  backup/               ← Backup
  kb/                   ← knowledge base / troubleshooting
  resources/            ← whitepapers, videos, external links
  partners/             ← partner program pages

The URL is the folder path. A file at src/content/docs/dr/workflows/failover.mdx renders at /docs/dr/workflows/failover. There is no slug field in frontmatter — the path is the slug.

File name rules:

RuleCorrectWrong
Lowercasefailover.mdxFailover.mdx
Hyphens, not underscoresprotection-plans.mdxprotection_plans.mdx
No spacesquick-start.mdxquick start.mdx
Descriptivecli-reference.mdxpage1.mdx

Where to put images:

text
public/docs/images/[section]/your-image.png

Reference them as /docs/images/[section]/your-image.png — always absolute, never relative.


Part 3 — Frontmatter

Every page starts with a YAML block between two --- fences:

yaml
---
title: "Failover"
description: "Promote the target site, validate workloads, and cut over traffic during a planned or emergency failover."
section: "Disaster Recovery"
category: "Workflows"
product: "Datamotive Platform"
version: "2.0.3"
status: "published"
sidebar_position: 1
tags:
  - failover
  - workflow
  - dr
keywords:
  - promote target site
  - failover steps
last_updated: "2026-05-27"
---
ParameterTypeRequiredDescription
titlestringrequiredPage title. Rendered as the H1, the browser tab title, and the sidebar label. Keep under 60 characters.
descriptionstringrequiredOne-to-two sentence summary. Used in search results and social previews. Keep under 160 characters.
sectionstringrequiredTop-level navigation section. Must match an entry in src/content/docs/_config.ts.
categorystringrequiredSub-section within the section. Must match an entry in _config.ts.
productstringrequiredOwning product. Use "Datamotive Platform" unless a product-specific value applies.
versionstringrequiredSolution version the page documents. Use "2.0.3" for current docs — keep this consistent across all pages.
statusstringrequiredPublishing status: draft, review, or published.
sidebar_positionintegerrequiredSort order within the category. Lower numbers appear higher.
tagsstring[]optionalLowercase, hyphenated tags for filtering and related-content logic. 3–6 per page.
keywordsstring[]optionalExtra search phrases not already in the title or description.
last_updatedstringrequiredISO date of the last substantive edit: YYYY-MM-DD.

Part 4 — Page structure rules

Every page follows the same shape:

text
---
[frontmatter]
---
 
[intro paragraph — no heading, 1–3 sentences]
 
## First H2 section
...
 
## Second H2 section
...

Heading hierarchy: Use ## (H2) for major sections, ### (H3) for sub-sections, #### (H4) sparingly. Never skip from H2 to H4. H2 headings appear in the right-rail table of contents.

Common markdown:

mdx
**Bold** for UI labels and key terms.
*Italic* for file names, titles, and new terms on first use.
`inline code` for flags, paths, config keys.
~~Strikethrough~~ for deprecated terms.
 
- Unordered list when sequence doesn't matter
- Nested item (two-space indent)
 
1. Ordered list when sequence matters
2. For multi-step procedures, prefer <Steps> instead
 
[Internal link](/docs/getting-started/quick-start)        ← always absolute /docs/ path
<ExternalLink href="https://example.com">External</ExternalLink>   ← never bare <a>

Code blocks must have a language tag (bash, powershell, typescript, python, go, yaml, json, sql, text, mdx, html, css):

mdx
```bash
systemctl status dm-mgmt
```

Part 5 — Component catalog

Every component below is globally available — just use the tag. For ready-to-paste examples of each one, open the MDX component placeholders page.

All MDX components available in Datamotive docs
ComponentUse it for
<Callout>Inline boxes — variants: info, note, tip, success, warning, error, prerequisite, security, configuration.
<MinimumVersionCallout>Flag a section that needs a minimum product version.
<UnsupportedPlatformCallout>Warn that a feature does not work on a given platform.
<RequirementCallout>List prerequisites at the top of a guide or tutorial.
<Steps>Numbered procedure with a visual guide rail. Use for any multi-step task.
<Tabs>Group OS, language, or mode variants of the same content.
<CodeGroup>Tabbed code-only block when only the code differs across languages.
<TerminalCommand>Single shell command with a copy button and $ prompt.
[object Object][object Object]Linked tiles guiding readers to related pages.
<ButtonLink>Call-to-action link styled as a button.
[object Object][object Object]Inline status chips (GA, beta, deprecated, required, version).
<ParameterTable>API or CLI parameter reference (name, type, required, default, description).
<SupportMatrixTable>Platform capability matrix with badge cells.
<CompatibilityTable>Source/target compatibility grid.
<FeatureComparisonTable>Edition or tier feature comparison.
<StatusTable>Lifecycle or release-stage tables.
<TroubleshootingTable>Symptom → cause → action grid.
<RequirementsTable>Hardware, network, and software prerequisites.
<GlossaryTable>Term-definition pairs.
<DocsTable>General-purpose table when no named table fits — supports React cells.
<APIEndpoint>Method + path chip placed above the parameters table.
<FileTree>Visual directory layout with folder and file icons.
<ResponsiveImage>Full-width screenshot or diagram.
<FigureWithCaption>Image plus a caption that carries information.
<ImageEmbed>Inline raster image with width controls.
<ArchitectureDiagram>Placeholder or rendered architecture diagram block.
<YouTubeEmbed>Embed a YouTube walkthrough by video ID.
<VideoEmbed>Self-hosted video with poster image.
<ExternalLink>Always use for third-party URLs — adds icon, target, rel attributes.
<RelatedDocs>Curated list of related docs pages at the end of a page.
<NextSteps>Recommended next-action block after a tutorial.
NaNOptional inline metadata strips (most pages do not need these).
[object Object][object Object]LaTeX math for reference pages — see Math components in placeholders.

Component usage rules at a glance

  • Every <Tabs> needs label="..." — accessibility requirement.
  • Every <Step> needs title="..." — verb-phrase, short.
  • Every image needs alt="..." — describe what the image shows, under 125 characters.
  • One <Callout> per topic — do not stack callouts back to back; fold into prose instead.
  • Use the most specific table component that fits — <DocsTable> only when none of the named ones do.
  • Always wrap external URLs in <ExternalLink> — never bare <a> or plain [text](https://...).

Part 6 — Page template (copy this)

Open a new file under src/content/docs/[section]/, paste this template, and replace every [PLACEHOLDER]. Sections you don't need can be deleted — keep the order of the ones you do keep.

mdx
---
title: "[Page title — under 60 chars, primary keyword near the start]"
description: "[1–2 sentence summary, under 160 chars. What will the reader find and do?]"
section: "[Section label — must match _config.ts]"
category: "[Category label — must match _config.ts]"
product: "Datamotive Platform"
version: "2.0.3"
status: "draft"
sidebar_position: [integer]
tags:
  - [tag-one]
  - [tag-two]
keywords:
  - [search phrase]
last_updated: "[YYYY-MM-DD]"
---
 
[Intro paragraph — 1–3 sentences. State what this page covers and what the reader will be able to do after reading it. No heading.]
 
## Prerequisites
 
<RequirementCallout title="Before you begin">
  - [Requirement one]
  - [Requirement two]
</RequirementCallout>
 
<MinimumVersionCallout version="[vX.Y.Z]">
  [Why this minimum version is required.]
</MinimumVersionCallout>
 
---
 
## Overview
 
[1–3 paragraphs of context. Include a diagram only if the architecture is non-trivial.]
 
<ArchitectureDiagram
  src="/docs/images/[section]/[diagram].svg"
  alt="[Describe what the diagram shows]"
  caption="[Key takeaway from the diagram.]"
/>
 
---
 
## [Main procedure heading]
 
<Steps>
  <Step title="[Step one — verb phrase]">
    [1–3 sentences explaining what and why.]
 
    ```bash
    [command]
    ```
  </Step>
 
  <Step title="[Step two]">
    [Content. Nest <Tabs> here if there are OS / language variants.]
  </Step>
 
  <Step title="[Step three]">
    [Content.]
 
    <Callout type="success" title="Verified">
      [How to confirm the step worked.]
    </Callout>
  </Step>
</Steps>
 
---
 
## Configuration reference
 
<ParameterTable
  rows={[
    { name: '[param]', type: '[type]', required: true,  description: '[What it controls.]' },
    { name: '[param]', type: '[type]', required: false, default: '[default]', description: '[What it controls.]' },
  ]}
/>
 
---
 
## Troubleshooting
 
<TroubleshootingTable
  columns={[
    { key: 'symptom', label: 'Symptom' },
    { key: 'cause',   label: 'Likely cause' },
    { key: 'action',  label: 'Action' },
  ]}
  rows={[
    { symptom: '[Symptom]', cause: '[Cause]', action: '[Action.]' },
  ]}
/>
 
---
 
## Related pages
 
<CardGrid cols={2}>
  <Card
    title="[Related page]"
    description="[One sentence on what the reader finds there.]"
    href="/docs/[section]/[page]"
  />
  <Card
    title="[Related page]"
    description="[One sentence on what the reader finds there.]"
    href="/docs/[section]/[page]"
  />
</CardGrid>

Part 7 — GitHub workflow

Branches: docs/feat/topic-name for new pages, docs/fix/topic-name for fixes, docs/update/topic-name for revisions. Always kebab-case.

Commit format:

text
docs(section): short present-tense summary under 72 chars
 
Optional body — explain WHY, not WHAT. Link related issues.
 
Refs: #issue-number

Examples:

bash
docs(dr): add failback workflow page
docs(core): fix broken link to replication engine concepts
docs(getting-started): update quick start for CLI v2.28

Workflow steps:

  1. Branch from main: git checkout -b docs/feat/my-new-page
  2. Create or edit your MDX file under src/content/docs/
  3. Add the page to src/content/docs/_config.ts so it appears in the sidebar
  4. Run the dev server locally and verify the page renders
  5. Compress any new images to under 200 KB before committing
  6. Open a PR against main and request review
  7. Address review comments and merge

Part 8 — Pre-publish checklist

Run through this before flipping status to "published".

Frontmatter

  • title is unique, under 60 chars, includes the primary keyword
  • description is under 160 chars and answers what will I find and do here?
  • section and category match _config.ts exactly (case-sensitive)
  • sidebar_position is set and does not collide with adjacent pages
  • last_updated is today's date in YYYY-MM-DD
  • At least three tags present

Structure

  • No # H1 in the body
  • Heading levels do not skip (H2 → H3 → H4, never H2 → H4)
  • Intro paragraph explains what the page covers without a preceding heading

Links and media

  • All internal links use absolute /docs/ paths
  • All external links use <ExternalLink>
  • Every image has descriptive alt text
  • Every <YouTubeEmbed> and <VideoEmbed> has a title prop
  • New images are under 200 KB and live in public/docs/images/[section]/

Code

  • Every fenced code block has a language tag
  • Commands have actually been tested
  • Placeholder values (e.g. YOUR_TOKEN_HERE) are accompanied by a <Callout> explaining them

Components

  • Every <Tabs> has a label prop
  • Every <Step> has a title prop
  • <RequirementCallout> present when the page has prerequisites
  • Page renders without console errors in the local dev server

Part 9 — Common MDX errors

SymptomCauseFix
Component renders as plain textTag name misspelled, or a component that is not registeredCross-check the spelling against the component catalog in Part 5.
Build fails: "Could not parse frontmatter"Invalid YAML — usually a missing quote, a tab, or a colon inside an unquoted stringWrap string values that contain colons in double quotes. Use spaces, not tabs.
Build fails: "Unexpected token" near a JSX tagUnclosed JSX tag or HTML-style self-close on a component that expects childrenEvery tag must close explicitly: <Callout>...</Callout>. Self-close only void components.
GFM table renders as pipe-separated textTable is inside a JSX block, or missing blank lines around itPut a blank line above and below the table. Use <DocsTable> when inside JSX.
Page shows two H1 headingsAn extra `# Heading` written in the bodyDelete the `#` heading. The H1 is auto-generated from the `title` frontmatter field.
Internal link goes to 404Relative path used, file renamed, or _config.ts entry missingUse absolute /docs/section/page paths. Confirm the file exists and is registered in _config.ts.
External link opens in same tab without iconPlain Markdown [text](https://...) used instead of <ExternalLink>Replace with <ExternalLink href="https://...">text</ExternalLink>.
Code block has no syntax highlightingLanguage tag missing after the opening backticksAdd the language tag: ```bash, ```yaml, ```typescript, etc.
<Tabs> renders all tabs stackedMissing label prop on <Tabs>Add label="Descriptive group name" to the opening tag.
Page does not appear in the sidebarsection/category values do not match _config.ts, or the page is not registered thereCheck the exact values in _config.ts and copy them into frontmatter. Add a new entry if needed.

What's next

Was this page helpful?