Skip to content

Docs Authoring Guide

This is the guide for DataReadyAI engineers writing the Nexa docs. The site is an Astro Starlight project at nexa-docs; all content is MDX under src/content/docs/. Read this before adding or restructuring pages so your change builds cleanly and lands in the right place.

The site is split into four topics (via the starlight-sidebar-topics plugin), each aimed at a distinct audience. A topic is a top-level directory under src/content/docs/ plus one entry in the starlightSidebarTopics([...]) array in astro.config.mjs.

Topic Directory Audience Route prefix
Using the Platform platform/ End users of Nexa /platform/
Deploy & Operate operate/ Customer platform teams installing Nexa /operate/
Developers & API developers/ Integrators calling the APIs /developers/
Internal Engineering internal/ DataReadyAI engineers (this topic) /internal/

Each topic’s sidebar groups are declared in astro.config.mjs with autogenerate: { directory: '...' }, so the sidebar mirrors the folder tree. Order within a group comes from each page’s sidebar.order front-matter field; the group label comes from the config, not the folder name.

The Developers topic additionally mounts an auto-generated API reference (starlight-openapi) from the specs in openapi/databricks-api.json, snowflake-api.json, and agents-api.json. Do not hand-write API endpoint pages; they come from those specs.

Nexa runs on a 2×2 matrix: AWS or Azure (cloud) crossed with Databricks or Snowflake (data platform). The cardinal rule of this docs set:

Use two reserved syncKey values so a reader’s choice follows them across the whole site (picking “Azure” on one page selects “Azure” everywhere):

Content that only applies to AWS deployments — EKS, ECR, IRSA/Pod Identity, Route53, Secrets Manager.
Content specific to the Databricks data platform — Unity Catalog, Delta, nexa-databricks-api.

Reach for tabs only where the content genuinely differs. If a step is identical on both clouds, write it once as plain prose. Over-tabbing makes pages hard to scan and easy to let drift out of sync.

Every page is Starlight MDX with YAML front matter. Import any components you use from @astrojs/starlight/components; the vetted set is Tabs, TabItem, Steps, Card, CardGrid, LinkCard, LinkButton, Aside, Badge, FileTree, and Code. Asides can also be written as :::note, :::tip, :::caution, and :::danger directives with no import.

  • Front matter: keep title and a specific one-sentence description (it is what /llms.txt and search index on). Preserve any existing sidebar: block.
  • Headings: ## and ### only — they build the page’s on-page table of contents. One concept per ##.
  • Structured facts (fields, ports, options, env vars) go in tables or ordered lists, not prose, so they survive extraction into plain text.
  • MDX escaping: a raw < or { in prose is parsed as JSX. Write “less than” or wrap the value in backticks. Any <Something> that is not a real imported component must be inside a code span.
  • Procedures: wrap ordered steps in <Steps>; put commands in fenced code blocks with a language tag so they are copy-pasteable.

Links between docs pages must be root-absolute with a trailing slash, for example [Connectors](/platform/connectors/overview/). The build runs starlight-links-validator, which fails on any link to a route that does not exist — a broken internal link breaks the build, it is not a warning.

Links into the auto-generated API reference under /developers/api/... are allowed and are excluded from the validator (those routes are injected at build time and the validator cannot see them in the content collection). When you are unsure a target exists, omit the link rather than guess.

  1. Create the MDX file in the correct topic directory. The route is the path under src/content/docs/ minus the extension — internal/runbooks/common-runbooks.mdx serves at /internal/runbooks/common-runbooks/.

  2. Add front matter with title, a self-describing description, and sidebar.order to position it within its group:

    ---
    title: "My New Runbook"
    description: "One sentence stating what this page covers and for whom."
    sidebar:
    order: 3
    ---
  3. Write the body. Lead with 1–2 sentences of standalone context, then the mechanism. Absorb any cloud/warehouse variants into synced tabs.

  4. Run the build locally (below) and fix any link-validation errors before opening a PR.

You do not need to touch astro.config.mjs to add a page inside an existing group — the sidebar autogenerates from the directory. Only edit the config to add a whole new group or topic.

  • Directorynexa-docs/
    • astro.config.mjs topics, OpenAPI mounts, plugins
    • Directoryopenapi/ API specs → generated reference
    • Directorysrc/
      • Directorycontent/docs/ all MDX pages
      • styles/global.css brand overrides
    • package.json

Local development and the build:

Terminal window
npm install
npm run dev # live preview at http://localhost:4321
npm run build # production build — runs link validation
npm run preview # serve the built dist/

npm run build is the gate. It fails on:

  • A broken root-absolute internal link (starlight-links-validator).
  • Invalid MDX — an unescaped < or {, or a <Component> that was not imported.

The build also emits /llms.txt and /llms-full.txt (via starlight-llms-txt), which is why every page needs a clean heading hierarchy and a specific description. The site is served as a static bundle from an Nginx container (Dockerfile + nginx.conf at the repo root) at https://docs.nexa-drai.com.