- name
- datadesigner-docs
- description
- Maintain the NeMo Data Designer Fern docs site under fern/. Use for any documentation change. Triggered by: "edit docs", "add doc page", "update docs", "rename page", "fix broken link", "add redirect", "preview docs", "publish docs", "regenerate notebooks", "update dev note", any request that touches `fern/`.
- metadata
- {"internal":true}
# Data Designer Docs Maintenance
Unified skill for adding, updating, moving, and removing pages on the NeMo Data Designer Fern docs site.
Current URL: **`docs.nvidia.com/nemo/datadesigner`** (see `instances` in [`fern/docs.yml`](../../../fern/docs.yml)). Source of truth for everything user-facing is `fern/`.
## Scope Rule
**ALL doc prose edits happen under `fern/`.** The remaining `docs/` directory is only for notebook source, generated Colab notebooks, docs scripts, and downloadable recipe scripts. `docs/notebook_source/*.py` remains canonical for notebook code. Concept pages, recipes, plugins, and Dev Notes prose live under `fern/versions/latest/pages/`.
## Versioning Model
`main` contains only the latest Fern authoring docs. Historical release snapshots live on the CI-managed `docs-website` branch and must not be edited on `main`.
```
fern/versions/
├── latest.yml ← authoring nav file
└── latest/pages/ ← authoring MDX tree
```
`docs.yml` on `main` registers only `slug: latest`. When you edit docs, edit `latest/pages/` and `latest.yml`.
Dev Notes are patched into the published latest docs by CI. Add new posts to `latest/pages/devnotes/posts/` and `latest.yml` on `main`.
For future Fern-native releases, do not copy page trees by hand on `main`. The release workflow snapshots `latest` into a frozen version on `docs-website`.
## Layout at a Glance
```
fern/
├── README.md ← maintainer cheat sheet
├── docs.yml ← title, theme, versions:, redirects, custom-domain
├── fern.config.json ← organization + fern-api version pin
├── main.css ← bundled NVIDIA theme CSS
├── assets/ ← logos, favicon, recipe assets, devnote post images (shared)
├── images/ ← /images/* references from MDX
├── styles/ ← per-component CSS (notebook-viewer, authors, metrics-table, …)
├── components/ ← React/JSX MDX components
│ ├── NotebookViewer.tsx ← renders converted .ipynb cells with outputs
│ ├── Authors.tsx ← devnote bylines (uses devnotes/authors-data.ts)
│ ├── MetricsTable.tsx ← benchmark tables w/ best-value highlight
│ ├── TrajectoryViewer.tsx ← multi-turn tool-call traces (research dev notes)
│ ├── BadgeLinks.tsx ← header shields (license, github, etc.)
│ ├── Tag.tsx, CustomCard.tsx, CustomFooter.tsx
│ ├── notebooks/ ← gitignored per-tutorial *.json + *.ts output
│ └── devnotes/ ← .authors.yml, authors-data.ts, per-post trajectory data
├── scripts/
│ └── ipynb-to-fern-json.py ← .ipynb → fern/components/notebooks/*.{json,ts}
└── versions/
├── latest.yml ← authoring navigation tree
└── latest/pages/ ← authoring MDX content
```
## URL Routing Rules
Fern's URL is computed from the **section/page titles in the active version YAML**, not the file path:
```
File system Published URL
──────────────────────────────────────────────────── ────────────────────────────────────────
latest/pages/concepts/columns.mdx /concepts/columns
latest/pages/concepts/tool_use_and_mcp.mdx /concepts/tool-use-and-mcp/overview
latest/pages/recipes/code_generation/text_to_sql.mdx /recipes/code-generation/text-to-sql
latest/pages/devnotes/posts/text-to-sql.mdx /dev-notes/text-to-sql-for-nemotron-super
```
Rules:
- **Section title → kebab-case slug**: `"Dev Notes"` → `dev-notes`, `"Code Generation"` → `code-generation`, `"Tool Use & MCP"` → `tool-use-and-mcp`.
- **Page title → kebab-case slug**: `page: Text-to-SQL for Nemotron Super` → `text-to-sql-for-nemotron-super` (the filename `text-to-sql.mdx` is irrelevant for routing).
- **Subdirectories in the file path are dropped** — `devnotes/posts/foo.mdx` becomes `/dev-notes/<page-title>` (no `/posts/`).
When in doubt, recompute by walking the page's position in the active version YAML and slugifying each title.
## Operations
### Add a Page
1. Pick the file location: `fern/versions/latest/pages/<subdir>/<filename>.mdx`. Underscores in filenames are fine — they don't affect the URL.
2. Write minimal frontmatter:
```mdx
---
title: "<Page Title>"
description: "One-line SEO description (or empty string)"
---
# <Page Title>
<content>
```
3. Add an entry under the appropriate `section:` in `fern/versions/latest.yml`:
```yaml
- page: <Page Title>
path: ./latest/pages/<subdir>/<filename>.mdx
```
4. The URL becomes `/<section-slug>/<page-title-slug>`. Update any cross-references in other MDX accordingly.
5. If the page is a Dev Note, add it to the `Dev Notes` section in `latest.yml`.
### Update a Page
Editing prose is straightforward — change the MDX, save. No mirror step (one canonical tree).
For title changes, also update the `page:` value in `latest.yml` *and* fix any incoming links pointing at the old slugified title.
### Move / Rename a Page (with Redirect)
1. `git mv` the file.
2. Update `path:` in `latest.yml`.
3. Update incoming links: `grep -rn "<old-slug>" fern/versions/latest/pages/`.
4. Add a redirect to `fern/docs.yml`:
```yaml
redirects:
- source: "/nemo/datadesigner/<old-section>/<old-slug>"
destination: "/nemo/datadesigner/<new-section>/<new-slug>"
```
Note redirects use the path-prefixed form because `instances[0].url` includes `/nemo/datadesigner`.
### Remove a Page
1. `grep -rn "<filename-or-slug>"` to find inbound links.
2. `git rm` the MDX file.
3. Remove the `- page:` entry from `latest.yml`.
4. Fix or remove all inbound links.
5. Add a redirect in `docs.yml` if the URL was public.
### Worked Example: Add a How-To Under Concepts
Request: *"Add a how-to about deduplicating generated rows."*
1. Create `fern/versions/latest/pages/concepts/deduplication.mdx`:
```mdx
---
title: "Deduplication"
description: "Strategies for removing duplicates from generated datasets"
---
# Deduplication
<content>
```
2. Add to `fern/versions/latest.yml` under the `Concepts` section:
```yaml
- page: Deduplication
path: ./latest/pages/concepts/deduplication.mdx
```
3. Published URL: `/concepts/deduplication` on latest.
4. `cd fern && fern check && fern docs dev` to verify.
### Worked Example: Rename with Redirect
Request: *"Rename `/concepts/seed-datasets` to `/concepts/input-datasets`."*
1. Update `page: Seed Datasets` → `page: Input Datasets` in `latest.yml`.
2. `git mv fern/versions/latest/pages/concepts/seed-datasets.mdx fern/versions/latest/pages/concepts/input-datasets.mdx` and update `path:`.
3. Add to `docs.yml`:
```yaml
redirects:
- source: "/nemo/datadesigner/concepts/seed-datasets"
destination: "/nemo/datadesigner/concepts/input-datasets"
- source: "/nemo/datadesigner/latest/concepts/seed-datasets"
destination: "/nemo/datadesigner/latest/concepts/input-datasets"
```
4. `grep -rn "/concepts/seed-datasets" fern/versions/latest/pages/` and rewrite hits.
---
## Content Guidelines
DataDesigner uses **Fern-native MDX components directly**. Do not use GitHub `> [!NOTE]` or MkDocs `!!! note` syntax — neither renders.
### Callouts
| Purpose | Component |
|---|---|
| Neutral aside | `<Note>...</Note>` |
| Helpful tip | `<Tip>...</Tip>` |
| Informational callout | `<Info>...</Info>` |
| Warning | `<Warning>...</Warning>` |
| Error / danger | `<Error>...</Error>` |
```mdx
<Tip>
Recipes assume an OpenAI provider. Configure with `data-designer config list`.
</Tip>
```
### Cards
Landing/index pages use `<CardGroup cols={N}>` + `<Card title="..." icon="..." href="...">`. Icons are Font Awesome names (no `:material-...:` shortcodes — those are MkDocs and render as text).
```mdx
<CardGroup cols={3}>
<Card title="Tutorials" icon="book-open" href="/tutorials/the-basics">
Step-by-step notebooks
</Card>
<Card title="Recipes" icon="hat-chef" href="/recipes/recipe-cards">
Ready-to-use examples
</Card>
</CardGroup>
```
### Header Badges (Landing Pages Only)
For shields-style badges (license, GitHub, model providers) at the top of an index page, use `<BadgeLinks>` from `fern/components/BadgeLinks.tsx`:
```mdx
import { BadgeLinks } from "@/components/BadgeLinks";
<BadgeLinks
badges={[
{ href: "https://github.com/...", src: "https://img.shields.io/badge/...", alt: "GitHub" },
]}
/>
```
This wraps a row of badge images in a flex container so they sit side-by-side rather than stacking.
### Page Layout
The landing pages use frontmatter `layout: overview` for a wider design with TOC + sidebar. Other valid values: `guide` (default), `reference` (full-width, no TOC), `page` (no TOC, no nav), `custom` (blank canvas). See [Fern docs](https://buildwithfern.com/learn/docs/configuration/page-level-settings#layout).
## Frontmatter
Match the PR #581 style — keep frontmatter minimal:
```yaml
---
title: "<Page Title>" # required
description: "" # required (may be empty string)
layout: overview # optional — only on landing pages
---
```
Do **not** add `position:` (we use explicit nav order in the version YAML), `date:`, or `authors:` to frontmatter — Fern's runtime treats `authors:` as a JSX scope variable and explodes when a component tries to reference it. For dev notes, see "Dev Notes" below.
## Dev Notes (Blog Posts)
Dev notes live under `fern/versions/latest/pages/devnotes/posts/`. They use the dev-notes kit components: **`<Authors>`, `<MetricsTable>`, `<TrajectoryViewer>`, `<ExpandableCode>`, `<CustomCard>`** (sources in `fern/components/`, CSS in `fern/styles/`).
Add the page and card to `latest.yml`. Release snapshots are handled by CI on `docs-website`.
### Authors Byline
Author registry: `fern/components/devnotes/.authors.yml` (source of truth) + `fern/components/devnotes/authors-data.ts` (typed copy that `Authors.tsx` imports). Edit both together.
```mdx
---
title: "<Post Title>"
description: "<one-line summary>"
---
import { Authors } from "@/components/Authors";
# <Post Title>
<Authors ids={["dnathawani", "ymeyer"]} />
<post body>
```
**Pass IDs as an explicit array literal**, not `<Authors ids={authors} />` — the bare `authors` identifier doesn't exist in Fern's MDX render scope.
To add a new author:
1. Append to `fern/components/devnotes/.authors.yml`:
```yaml
newauthor:
name: New Author
description: Researcher at NVIDIA
avatar: https://avatars.githubusercontent.com/u/<id>?v=4
```
2. Add the same entry to `fern/components/devnotes/authors-data.ts` (no auto-sync).
### Benchmark Tables
Use `<MetricsTable>` instead of plain markdown tables when you have numeric model comparisons. Auto-highlights the best value per column.
```mdx
import { MetricsTable } from "@/components/MetricsTable";
<MetricsTable
headers={["Model", "BIRD EX (%)", "Val Loss (↓)"]}
rows={[
["Baseline", 26.77, 1.309],
["Ours", 41.80, 1.256],
]}
lowerIsBetter={[2]}
/>
```
`lowerIsBetter` takes column indices; everything else is "higher is better".
### Trajectory Viewer
For multi-turn agent traces (search/open/find/answer), put the trajectory data in a typed module under `fern/components/devnotes/<post-slug>/<example>.ts`:
```ts
import type { TrajectoryViewerProps } from "@/components/TrajectoryViewer";
const trajectory: Omit<TrajectoryViewerProps, "defaultOpen"> = {
question: "...",
referenceAnswer: "...",
goldenPassageHint: "⭐ = golden passage",
summary: "Example: 31 turns, 49 tool calls",
turns: [
{ turnIndex: 1, calls: [{ fn: "search", arg: "..." }] },
// ...
{ turnIndex: 31, calls: [{ fn: "answer", body: "..." }] },
],
};
export default trajectory;
```
Then in the post:
```mdx
import { TrajectoryViewer } from "@/components/TrajectoryViewer";
import trajectory from "@/components/devnotes/<post-slug>/<example>";
Auf GitHub ansehen