From 76ad4bef9c83363379ff36edf2fb00e441cabc58 Mon Sep 17 00:00:00 2001 From: Brian Love Date: Wed, 9 Sep 2026 21:50:33 -0700 Subject: [PATCH] docs(gtm): refresh the nav cta_id register and make it self-checking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The taxonomy's Nav section documented `nav_get_started`, `nav_docs`, `nav_pricing`, `nav_github`, `nav_npm` and `nav_cockpit`. Three of those were already not emitted before the navbar rebuild, so this register had drifted silently — and the rebuild replaced almost all of the rest. Records the real set (twenty panel ids plus the bar's own), notes that every one also exists with a `mobile_nav_` prefix because `trackNavItem` applies the surface, and lists what retired: `nav_demo_langgraph` / `nav_demo_ag_ui` are now `nav_docs_demo_*` since the Demo dropdown was absorbed into the Docs panel. More usefully, `nav-config.spec.ts` now asserts the doc mentions every id the nav emits. The ids are data, so the register can be checked rather than trusted. Removing one from the doc fails the test naming it. Co-Authored-By: Claude Opus 5 --- .../src/components/shared/nav-config.spec.ts | 27 ++++++++++++++++- docs/gtm/taxonomy.md | 30 ++++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) 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**