[docs] reorganize into doc tabs - #1004
Merged
Merged
Conversation
Adopt the docs-theme-extras `docTabs` layout so the left nav shows one group at a time instead of the whole version tree. Four tabs, in order: Documentation (default), Integrations, Reference, Release notes. Each tab is a real directory under the version root, so this is a content move as much as a config change: - `documentation/` is new and takes every subject directory that used to sit at the version root (about, agent, llm, mcp, security, setup, …). - `integrations/` and `reference/` already existed and stay where they are. - `release-notes/` is new and takes `reference/release-notes.md` and `reference/versions.md` back out of the Reference tab. - `not-in-version.md` deliberately stays at the version root: navbar.html and sidebar.html hardcode `<version>/not-in-version` for the version-switch fallback. All ten published version roots move together, not just latest/main. Two things force that. The theme enables the tab band wherever two or more of the configured directories exist, and `integrations/` + `reference/` already existed in 1.0.x–1.4.x and 2.2.x — so landing the config alone would switch tabs on for versions with no `documentation/` directory to root the nav in. And `assets/agw-docs/` is shared unversioned by every version, so a half-migration would leave its ~218 files' link paths correct for one group and wrong for the other. Link surface updated in the same change: the `link`, `link-hextra`, `card`, `badge`, and `redirect` shortcodes all resolve version-root- relative paths, plus hardcoded URLs in layouts, `static/_worker.js`, the Playwright fixtures, and the doc-test scripts' examples. `static/_redirects` gains a rule per moved directory per version, and existing redirect targets were repointed, so every previously published URL still resolves. Pages with legacy `aliases` keep them and gain the moved-path form alongside. Verified: `hugo --gc --minify` is clean, and an internal link check over the built site finds the same 23 pre-existing dead links as origin/main — no regressions, and the tab band plus per-tab nav scoping render on all four tabs. Signed-off-by: Art Berger <art.berger@solo.io>
The doc-test front matter names its source guides by repo-relative path, in
two forms the link rewrite did not cover:
- file: content/docs/<mode>/<version>/<path>.md
- file: ${versionRoot}/<path>.md (expanded by doc_test_extract)
Both now carry the documentation/ segment. Without this the generator dies
on the first scenario with FileNotFoundError rather than failing a test, so
nothing runs at all.
Verified against a generation run of the same 458 scenarios on origin/main:
identical scenario count, identical selected_count and selected_test_count in
all 458 manifests, and 450 of 458 generated scripts byte-identical. The other
eight differ only in the `# Source:` line numbers, shifted by one because
those pages gained a companion alias line.
Signed-off-by: Art Berger <art.berger@solo.io>
Integrations pages that only pointed at a Documentation guide are now a single entry that goes straight there, and the two tabs that had almost no icons have a full set. Standalone integrations: - llm-providers/ was an index plus eight per-provider stubs, every one of them a `redirect` into documentation/llm/providers/. It collapses to one `llm-providers.md` that redirects to the section. - mcp-servers/ collapses the same way to documentation/mcp/connect/. The three transport pages restated what the connect guides already cover; the one thing the landing had that the guides did not — the "why put agentgateway in front of an MCP server" table — moves into documentation/mcp/connect/_index.md rather than being dropped. Kubernetes integrations: - New LLM providers and MCP servers entries, pointing at documentation/llm/providers/ and documentation/mcp/. Every child of this section carries weight 10, so ordering is alphabetical by title and the two land directly after LLM clients and MCP clients. - mcp-clients was a single page listing five IDEs. It is now a section with a page per client, matching how llm-clients is already organised: the shared setup (prerequisites, MCP endpoint URL, auth, next steps) stays on the landing, and each client gets its own page reusing a per-client asset. The two `mcp-clients-k8s` doc-test blocks live in the shared setup, so the scenario is unchanged — the regenerated script still carries both. Release notes landing: an explicit card grid, including a Changelog card out to the GitHub releases page. It also sets `disableCards: true` — the auto child-card grid is only suppressed by that flag, not by the presence of manual cards, despite what auto-section-cards.html's comment says. Icons: every page in the Integrations, Reference, and Release notes tabs now has one (234 added; 46/46, 25/25 and 26/26 coverage per tab). The rule follows the Documentation tab — a brand logo from static/integrations/ where one exists, otherwise the group's Material Symbol. The generated reference widget pages carry theirs through the content adapters' params dict. Note that card icons resolve differently from front-matter ones: card.html calls Hextra's icon partial unguarded, so a card icon must be an SVG path or a data/icons.yaml key — a Material Symbol name there aborts the build. static/_redirects gains 52 rules so every collapsed integrations URL still resolves, using the exact targets the deleted stubs redirected to. Signed-off-by: Art Berger <art.berger@solo.io>
Ten of the icons added in the previous commit carried hardcoded brand colours, so Helm, Argo, Istio, Claude and others rendered in blue/orange next to the grey Material Symbols instead of matching them. The repo already had the mechanism: colour logos live in static/integrations/ (the homepage grid uses them) and monochrome nav variants live in static/integrations/providers/bw/, where every file is `fill="currentColor"` — which is why the LLM provider pages in the Documentation tab always looked right. This adds the missing variants and points the icons at them. Eight convert by swapping the colour for currentColor, because none of them paints a white knock-out layer: claude, istio (its two tones survive via opacity), langchain, langfuse, aws, google-cloud, plus helm and argocd. helm and argocd needed redrawing rather than substituting: both paint white detail on top of a solid disc, so recolouring every fill gives a filled blob. They are now line art — an outlined disc with the detail kept as a stroke, which reads as a ship's wheel and a set of rings. Two icons changed rather than converted: - opencode's mark is two greys with no outline, and collapses to a filled square in a single colour. It falls back to /integrations/code.svg, which already inherits. - kagent was pointing at the Kubernetes logo, which was simply wrong — kagent is not Kubernetes. It takes the web-uis group symbol instead. Verified by rendering each new variant to PNG and looking at it, then scanning the built site: 0 hardcoded colours across 74,515 inlined nav and card icons on 2,672 pages, with the dead-link set unchanged. Note that `rm -rf public` alone is not enough to re-check this — the stale inlined SVGs survive in resources/, so a verification build needs that removed (or --ignoreCache) or it reports colours that are no longer in the source. Signed-off-by: Art Berger <art.berger@solo.io>
Deploying agentproxy with
|
| Latest commit: |
19d9519
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://5e33f9ea.agentproxy.pages.dev |
| Branch Preview URL: | https://adb-doctabs.agentproxy.pages.dev |
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Integrations was a flat list of nine-plus siblings. It now groups by subject:
LLM/ providers, clients, routing (k8s), observability
MCP/ servers, clients
CI-CD/ argo
+ auth, cloud-providers, networking, web-uis, istio unchanged
Argo moves under CI/CD, and vLLM Semantic Router and KServe move under
LLM > Routing. Nested titles shed the now-redundant prefix ("LLM clients" ->
"Clients" under LLM), and weights put the primary child first: providers before
clients, servers before clients.
The provider and MCP-server guides change DIRECTION. They used to live in
Documentation with an Integrations stub redirecting to them; now the content
lives in Integrations and Documentation carries the pointer:
integrations/llm/providers/ <- documentation/llm/providers/ (22 / 15 pages)
integrations/mcp/servers/ <- documentation/mcp/connect/ (standalone)
documentation/llm/providers -> points at the Integrations page
documentation/mcp/connect -> points at the Integrations page
Kubernetes keeps its MCP-server guides (static-mcp, dynamic-mcp, virtual,
https, session) in Documentation — they are core guides, not integrations — so
its Integrations > MCP servers stays a pointer INTO Documentation. The two modes
differ here on purpose.
Icons are gone from the docs nav, so there is nothing to keep in sync as pages
move (692 removed, plus 11 hand-written card icons and 5 in the content
adapters). The only survivors are the LLM provider pages, whose brand logos also
drive the provider card grid. The three mode landings above the version roots
keep theirs — they belong to the /docs/ index, not to a version's nav.
Archived versions moved too, for the same reason the docTabs partition had to
cover them: assets/agw-docs/ is unversioned, so a link rewritten there resolves
against whichever version renders it. Leaving 1.0.x-2.2.x behind put 91 dead
links into them, which is how this was caught.
static/_redirects gains 258 rules. The two Documentation sections keep a real
page at the directory URL, so only their children need a rule; the renamed
groups get base, trailing-slash, and wildcard.
Verified: hugo builds clean, the dead-link set is byte-identical to origin/main
(23, all pre-existing), and doc-test generation still produces 458 scenarios
with their sources resolving to the new paths.
Signed-off-by: Art Berger <art.berger@solo.io>
…yout main moved on while this branch was open — most substantially PR #990 ("Observability updates for Kubernetes"), which restructured observability at the PRE-docTabs paths, plus #998, #1006 and the timeout/agentcore edits. Resolved by rule rather than by hand, because the two changes are orthogonal: main's CONTENT wins for every file it touched, and this branch's LOCATION wins. All 63 of main's content changes were re-applied at their docTabs path — for these, `<version>/observability/…` becomes `<version>/documentation/observability/…` — and this branch's transformations (the tab path prefix, the Integrations regrouping, icon removal) were re-applied on top. Nothing of this branch's own work is lost that way, because its edits to those files were only path rewrites and icon removal. The trap here is not the 30 conflicts, it is the files that merge CLEANLY. Most of main's new observability pages had no counterpart on this branch, so git happily added them at `<version>/observability/…` — a path that is outside every tab in this layout, where they would render with no tab band and no nav. 35 such duplicates were removed after their content was applied at the correct path. Two files needed manual repair, both from git pairing a `latest` file of main's against an ARCHIVED file of this branch by rename detection: - 1.3.x/documentation/observability/_index.md (left conflict markers) - 1.3.x/documentation/observability/otel-stack.md (mis-merged SILENTLY) Both restored from this branch's side; main never touched 1.3.x. The silent one was caught by diffing every archived version root against the pre-merge commit, which is now the check to run after any merge into this branch — archived roots must come out byte-identical. Note the conflict markers were eight brackets deep, not seven, so a `^<<<<<<< ` grep misses them. Verified: hugo builds clean, and an internal link check finds the same 44 dead links as origin/main built at the same commit — no regressions. (Main itself went from 23 to 44; the 21 new ones arrived with #990/#1006 and are not addressed here.) Signed-off-by: Art Berger <art.berger@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Cloudflare allows 2,000 static and 100 DYNAMIC redirects per _redirects file,
and any rule carrying a splat or a :placeholder is dynamic. Writing the doc-tab
moves out per version had reached 278 dynamic rules — nearly three times the
ceiling, which would have broken the deploy rather than degrading quietly.
Collapsed to 51. `:section` and `:version` each match one segment, so a single
rule covers kubernetes and standalone across every published version, and a
trailing `*` covers the bare path, the trailing-slash form, and everything
beneath it at once. Static rules are untouched at 92.
Order is load-bearing, since Cloudflare applies the first rule that matches:
the paths that left Documentation entirely (llm/providers, mcp/connect) precede
the plain llm*/mcp* rules that would otherwise swallow them, and
vllm-semantic-router precedes vllm.
Three cases the compact form does not cover on its own, all verified rather
than assumed:
- llm/inference and llm/multiple-inference-pools set an explicit `url:`, so
they do not publish where their file path implies. A parent's `url:` does
NOT move its children, so inference-routing keeps the plain documentation/
prefix while the landing goes to documentation/inference.
- integrations/llm-providers and integrations/mcp-servers were real published
stub pages, and two of their leaves were renamed on the way (azure-openai ->
azure, openai-compatible -> custom, streamable-http -> http).
Checked by replaying the rule file the way Cloudflare does — first match wins,
:placeholder is one segment, * is greedy — over every URL origin/main publishes:
2,584 URLs, 304 still served directly, 2,280 covered by a redirect, 0 uncovered.
Pages carrying a `url:` override are excluded, since they never published at
their file path in the first place.
Signed-off-by: Art Berger <art.berger@solo.io>
Closed
Discover test cases — the "Get changed markdown files" step trimmed its file
list with `xargs`, which re-wraps output at about 4,096 characters. On a PR this
size that turned a single-line `files=...` into a multi-line value and the step
died with "Unable to process file command 'output' successfully". Trim with sed
instead, and write through the heredoc form so length can never break the
format again. Not specific to this PR: any change touching a few hundred pages
would have hit it.
Static + content checks — otel-stack.md used the deprecated
`{{< tabs items="..." >}}` form with `tabName=` on each tab, which
tab-syntax.spec.ts rejects. Converted to per-tab `name=`. This arrived with the
observability rework rather than from this branch (origin/main carries the same
two lines), but it fails here, so it is fixed here.
Signed-off-by: Art Berger <art.berger@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io> # Conflicts: # assets/agw-docs/pages/security/access-logging.md
Two defects from merging main into the docTabs layout. Rename detection paired main's standalone/main/.../access-logs/view.md with the docTabs standalone/LATEST file, because the two version trees are near-identical. The guardrails section from #1005 landed in latest and never reached main. Move it to the tree #1005 targeted. Also prefix the guardrails cross-link with documentation/, since llm/ lives under the documentation tab now. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Kristin Brown <kristin.brown@solo.io>
The restructure in #990 deleted latest/security/access-logging and main+latest/observability/tracing, but other pages still link to them. Add stubs at the docTabs paths, matching the one #990 already left at main/documentation/security/access-logging. The tracing stubs set sidebar.exclude so a "Tracing" entry does not sit beside the new "Traces" section. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Kristin Brown <kristin.brown@solo.io>
"Discover test cases" has failed on every run of this branch. The list of changed markdown files reached the "List test cases" step as an env var, and on a PR this size it is ~263 KB. Linux caps a single environment string at MAX_ARG_STRLEN (128 KiB), so execve failed with "Argument list too long" before that step's bash started -- the annotation names bash, not the python script, which runs fine on the same input. This is the same oversized list that broke the previous step in 16955aa; fixing the write moved the failure one step downstream to the read. Write the list to $RUNNER_TEMP/changed-files.txt, one path per line, and read it back into an array. Each path is then its own short argv entry, so only the total matters (263 KB against a ~2 MB ARG_MAX), and no single string approaches the per-string cap. Verified locally under bash: 3909 paths in, 1038 test cases discovered, 40 shards, largest per-shard SHARD_TESTS 3069 bytes. The no-file fallback still selects full discovery for scheduled and dispatch runs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Kristin Brown <kristin.brown@solo.io>
The kubespec widgets carry ~3300 "Documentation References" links of the form ../../../llm/rbac/. From <version>/reference/api-kubespec/<kind>/ that resolves to <version>/llm/rbac/, which docTabs moved to <version>/documentation/llm/rbac/. This was the bulk of the link checker's 275 errors. render.go needs no change. It builds each href as "../../../" + the path of the page that referenced the schema field, and extract_rendered_yaml.py derives those paths from the built site -- run against this branch it already emits documentation/... keys. The committed HTML is simply stale, generated from a pre-docTabs build. This commit brings it in line with what the next reference-docs run produces, so that run is a no-op rather than churn. Each href was remapped with the wildcard rules in static/_redirects, in Cloudflare's first-match order, then verified against the built site: 3322 rewritten, 18 already correct, 0 unresolved. Only ks-doc-link hrefs differ -- 1291 changed line pairs, none differing outside the href. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Blog posts and a few doc pages still linked to pre-docTabs URLs. Blogs: 38 links across 11 posts, remapped with the static/_redirects wildcard rules and verified against the built site. The redirects would have caught these at runtime, but only as 301s, and agentgateway.dev applies a limited number of rules. Doc pages: four relative links that survived the move because they are relative and so kept resolving to a plausible-looking wrong path -- ../../api-types and ../api-types from the standalone LLM provider pages, and ../connect/stdio from mcp-observability. Converted to link-hextra with absolute paths so a future section move breaks the build loudly instead of silently retargeting them. Local lychee run over the built site, with the same config and flags CI uses: 463818 links checked, 0 errors, down from 275. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Nadine2016 <nadine.spies@solo.io>
Signed-off-by: Nadine2016 <nadine.spies@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Carries main's content into the docTabs layout. Git's rename detection mis-routed several changes between version trees, because every version root was partitioned into the same documentation/integrations/reference tabs and the trees look alike to similarity matching. Corrected: - backend.md landed in 1.2.x and 1.3.x; main added it to latest and main. - The "Backend policy fields" section landed in 1.2.x and 1.3.x; main added it to latest and main. - The access-log OpenTelemetry preset section landed in standalone/latest; main added it to standalone/main. - The security/access-logging aliases were swapped between latest and main, so each tree aliased the other's path. Also in this merge: - Release notes for both modes take main's version wholesale. Main reset the `main` tree to a fresh 1.6.x cycle, and the branch's only change to that file was link repointing. - The three conflicted generated API reference files take main's regenerated output, with the ks-doc-link hrefs repointed at the docTabs paths. Verified byte-identical to main apart from hrefs. - 39 hand-written link-hextra and card paths that main added are repointed at their docTabs tab. - after-title.html and the agentgateway-crds..md typo duplicate are dropped, both deleted in main. The branch's only edit to after-title was a comment, and main replaced the slot with under-heading.html. - filter-order.md takes main's weight: 5 reordering. KNOWN, INHERITED FROM MAIN: main added two links to shared asset bodies without a version gate that covers the frozen trees, so 1.0.x, 1.1.x, 1.2.x, 1.3.x, 1.4.x, and 2.2.x each link a page that exists only in latest and main. 18 broken in-body links total. These break identically on main and are not a merge regression. Signed-off-by: Kristin Brown <kristin.brown@solo.io>
`backend.tcp.connectTimeout` and `backend.http.requestTimeout`, and the `resiliency/timeouts/backend` page that documents them, arrived in 1.5. Both shared assets picked up the new content ungated, so 1.0.x-1.4.x and 2.2.x described a feature they do not have and linked to a page that does not exist in them — 6 dead links, 12 occurrences. `exclude-if` rather than `include-if` so a new version needs no edit here. Note the list is not what covers the archived versions: hugo.yaml params.versions registers only 1.5.x and 1.6.x, and a version gate drops its content wholesale in an unregistered version directory. That is why 2.2.x is correctly excluded without being named. The list states the intent and takes effect for any version that is registered. The table rows carry their markers at the START and END of the row line, not on lines of their own: a marker on its own line inside a table truncates the table at that point. Verified against rendered output: 4 table rows in every archived version and 6 in latest and main, with the request and per-try rows intact everywhere; the webhook-timeout section absent in archived versions with Step 3 still following it. Dead internal links go from 52 to 46 (89 to 77 occurrences) with none newly broken, which puts the branch at 0 links introduced and 3 removed against its state before the main merge. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: Art Berger <art.berger@solo.io>
Signed-off-by: Nadine2016 <nadine.spies@solo.io>
Nadine2016
approved these changes
Sep 4, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adopt new doc tabs Hugo theme feature to organize all versions and standalone/kubernetes sections into doc tabs:
documentation, integrations, reference, release-notes. Includes updates to links, and reference docs gen workflow.