diff --git a/apps/website/src/components/shared/nav-config.spec.ts b/apps/website/src/components/shared/nav-config.spec.ts index a2f76a371..6f42468fc 100644 --- a/apps/website/src/components/shared/nav-config.spec.ts +++ b/apps/website/src/components/shared/nav-config.spec.ts @@ -1,4 +1,4 @@ -import { existsSync } from 'node:fs'; +import { existsSync, readFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import { describe, expect, it } from 'vitest'; @@ -7,6 +7,11 @@ import { docsConfig } from '../../lib/docs-config'; import { getAllSolutionSlugs } from '../../lib/solutions-data'; const APP_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'app'); +const TAXONOMY = join( + dirname(fileURLToPath(import.meta.url)), + '..', '..', '..', '..', '..', + 'docs', 'gtm', 'taxonomy.md', +); /** * `/docs/:library/:section/:slug` is a dynamic route, so a page file cannot @@ -88,4 +93,24 @@ describe('nav-config', () => { 'Pricing', ]); }); + + /** + * The GTM taxonomy is the register analytics work reads to know which + * `cta_id`s exist. It is hand-maintained prose, and it had silently drifted + * before the navbar rebuild — it still listed `nav_get_started`, `nav_npm` + * and `nav_cockpit`, none of which the nav emitted any more. + * + * The nav's ids are data, so the doc can be checked against them instead of + * trusted. Only the `nav_` surface is asserted: `mobile_nav_` is the same + * list with a different prefix, applied by `trackNavItem`, and the doc says + * so once rather than duplicating twenty entries. + */ + it('documents every nav cta_id in the GTM taxonomy', () => { + const taxonomy = readFileSync(TAXONOMY, 'utf8'); + const undocumented = navItems() + .map((item) => `nav_${item.ctaId}`) + .filter((id) => !taxonomy.includes(id)); + + expect(undocumented).toEqual([]); + }); }); diff --git a/docs/gtm/taxonomy.md b/docs/gtm/taxonomy.md index 7c89ecc54..1613f6f04 100644 --- a/docs/gtm/taxonomy.md +++ b/docs/gtm/taxonomy.md @@ -158,7 +158,35 @@ Browser events never fire unless the consumer explicitly opts in. See `libs/tele **Nav** -- `nav_get_started` `nav_docs` `nav_pricing` `nav_github` `nav_npm` `nav_cockpit` +The navbar was rebuilt on 2026-09-08 into four triggers, three of which open panels. +Every panel destination is data in `apps/website/src/components/shared/nav-config.ts`, +and `trackNavItem` prefixes each item's `ctaId` with the surface — so **every id below +also exists with a `mobile_nav_` prefix**, emitted by the same items in the mobile +drill-in drawer. Add a destination there and its id appears on both surfaces +automatically; there is no second list to keep in sync. + +- Libraries panel — `nav_libraries_langgraph` `nav_libraries_ag_ui` `nav_libraries_chat` + `nav_libraries_render` `nav_libraries_choosing_an_adapter` +- Docs panel — `nav_docs_documentation` `nav_docs_quick_start` + `nav_docs_choosing_an_adapter` `nav_docs_guides` `nav_docs_concepts` + `nav_docs_api_reference` +- Docs panel, external demos — `nav_docs_demo_langgraph` `nav_docs_demo_ag_ui` + (derived from `DEMOS` in `lib/demos.ts`, so a new demo adds its own id) +- Solutions panel — `nav_solutions_customer_support` `nav_solutions_analytics` + `nav_solutions_compliance` `nav_solutions_pilot_to_prod` `nav_solutions_blog` + `nav_solutions_about` +- Bar itself — `nav_pricing` `nav_github` `nav_talk_to_us` +- Mobile drawer only — `mobile_nav_docs_page` (any link inside the docs tree, with the + page title in `cta_text` and the library in `library`) + +- retired 2026-09-08: `nav_demo_langgraph` `nav_demo_ag_ui` (the hand-rolled `Demo ▾` + dropdown was absorbed into the Docs panel — the demos are now + `nav_docs_demo_langgraph` / `nav_docs_demo_ag_ui`); `nav_docs` (now + `nav_docs_documentation`); `nav_pilot_to_prod` (now `nav_solutions_pilot_to_prod`) +- retired earlier, date unknown: `nav_get_started` `nav_npm` `nav_cockpit` — these were + already listed here but no longer emitted by the pre-redesign nav either, so this + section had drifted before the rebuild. Recorded rather than silently dropped, in case + a dashboard still filters them. **Footer**