A command-line tool that generates and previews the VTEX Help Center navigation (navigation.json). It is designed for CI/CD and local inspection.
- Generates a unified, multilingual navigation from the Help Center content repositories
- Validates output against a JSON Schema plus custom rules
- Includes a simple viewer for quick inspection
npm install -g vtexhelp-nav-cli
# or
npx vtexhelp-nav-cli# Generate navigation (writes ./generated-navigation.json)
vtex-nav gen
# View a navigation file in the terminal
vtex-nav view --file ./generated-navigation.json
# Validate a navigation file (schema + custom checks)
vtex-nav validate ./generated-navigation.json --strictFor the full list of flags, run vtex-nav gen --help and vtex-nav view --help.
Generation pipeline:
- Scan content repositories (docs/en|es|pt/*)
- Build category hierarchy from the natural folder structure
- Link cross-language files and normalize localized names/slugs
- Transform into the navigation schema
- Validate (JSON Schema + custom checks) and write output
- All sections respect the natural folder hierarchy. If the repository is nested, navigation is nested; if folders are flat, navigation is flat.
- Announcements
- Directory layout: year/month/articles
- Within each year, months are categories; within each month, articles are listed
- Month articles are ordered by the YYYY‑MM‑DD prefix in the filename/slug (newest first)
- Tracks
- Track articles are ordered by the
orderfield in frontmatter; we also prefix article titles with positional numbers for better UX
- Track articles are ordered by the
- Tutorials, FAQ, Troubleshooting, Known Issues
- Follow folder hierarchy; documents are sorted alphabetically unless an
orderis present (see below)
- Follow folder hierarchy; documents are sorted alphabetically unless an
- The generator reads
metadata.jsonin category folders (for each language) when present- Uses
nameto set localized category titles - Uses
orderto sort categories; this applies to all sections - Falls back to legacy
order.jsonif needed
- Uses
- When metadata is absent, names are derived from folder names and categories are sorted alphabetically
- Categories and documents use LocalizedString slugs (en/es/pt)
- Categories across languages are merged by their English slug so they are treated as a single localized entity
- Document slugs are derived from filenames; for Announcements we only read the leading date to sort but do not alter names
A folder can designate one of its direct markdown files as the category's landing page (cover) by adding categoryCover: true to its frontmatter. When a cover is set, the category node gets type: "markdown" and its name/slug are taken from the cover file rather than the folder name. The other direct files and subcategories remain in children.
If more than one file in the same folder is marked categoryCover: true, a warning is logged and the folder falls back to a regular type: "category".
To mark a file as cover, add to its frontmatter:
categoryCover: truecategoryCover is deduplicated by slugEN, so it doesn't matter which language file carries the flag — the cover still applies to the EN/ES/PT versions of that document. However, by convention it should only be set on the PT file. Setting it on an EN or ES file still works, but logs a [COVER] warning (visible with --show-warnings and in the --report markdown report) pointing to the file that should be fixed.
Example output for a cover-backed category:
{
"type": "markdown",
"name": { "en": "Account settings - Overview", "es": "...", "pt": "..." },
"slug": { "en": "account-settings-overview", "es": "...", "pt": "..." },
"origin": "",
"children": [
{ "type": "category", "name": { ... }, "slug": { ... }, "children": [...] }
]
}See also: Troubleshooting guide at docs/troubleshooting.md
- JSON Schema (Draft‑07) at
source/schemas/navigation.schema.json- name and slug are LocalizedString objects with en, es, pt keys
- Categories: type=category, children >= 1
- Documents: type=markdown, children can be empty or non-empty (when acting as a category cover)
- Additional properties are disallowed
- Custom checks
- Sibling categories under the same parent must have unique English slug
- Current content check also flags duplicate slugs anywhere in a section (not just siblings). This is conservative and may report Announcements months across different years. We plan to scope this to siblings only.
- gen: generate navigation
- Common flags:
--content-dir,--output,--languages,--sections,--branch,--verbose,--show-warnings
- Common flags:
- view: inspect a navigation file in the terminal
- validate: validate a navigation file against the schema + custom rules
You can provide a .env with:
VTEX_NAVIGATION_URL=https://newhelp.vtex.com/navigation.json
DEFAULT_OUTPUT_PATH=./navigation.json
AUTO_FORMAT_JSON=true
REQUEST_TIMEOUT=30000
Definitions are in source/schemas/navigation.schema.json. A minimal shape:
{
"navbar": [
{
"documentation": "announcements|tracks|...",
"name": { "en": "...", "es": "...", "pt": "..." },
"slugPrefix": "...",
"categories": [
{
"type": "category",
"name": { ... },
"slug": { ... },
"children": [
{ "type": "markdown", "name": { ... }, "slug": { ... }, "children": [] }
]
}
]
}
]
}
npm install
npm run build
npm run devTemporary caches created by the generator (safe to delete):
.vtexhelp-content.vtexhelp-known-issues
- Node.js >= 16
- Git (for content repository cloning)
MIT