solo-io / solo-io/docs-theme-extras
reuse-image: version overrides resolve by convention, dark variants do not
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- Avg merge
- 18h 13m
- Merged PRs (30d)
- 20
Description
Summary
reuse-image resolves one axis by convention and the other by explicit parameter, and I think that asymmetry is the bug rather than any single rendering behavior.
- Version overrides are automatic.
utils/resolve-versioned-image.htmlprefersassets/<dir>/<version>/<file>over the bare path with no author input. A page writesimg/foo.pngand a version-specific override is picked up wherever it exists, and dropped again when it is removed. - Dark variants are not. A dark counterpart needs an explicit
srcDark=on the call, even though<stem>-dark.<ext>is a rigid naming convention across every consumer repo, and even though the screenshot harnesses generate the dark file by that convention automatically.
So the same authoring model gives one override for free and makes the other manual. That is worth closing, but the obvious fix regresses kgateway, so this issue proposes a sequence rather than a patch.
Where this surfaced
agentgateway/website#999 converts 21 provider tabs in the standalone LLM quickstart from the legacy reuse-image-light + reuse-image-dark pair to a single reuse-image. Its Playwright spec captures a light and a dark baseline per provider, and docs-image-map.json declares a -dark.png destination for all 21, but 20 of the 21 tabs are written as {{< reuse-image src="…" >}} with no srcDark. Per reuse-image.html, a call with no srcDark takes the SINGLE branch and emits one figure shown in both modes, so that PR publishes 20 dark PNGs no page ever references.
That is fixable in the PR by adding srcDark to 20 tabs. The reason it is filed here instead is that under convention-based resolution those 20 edits would not have been necessary at all.
Why auto-discovery cannot just be turned on
Making the SINGLE branch look for <stem>-dark.<ext> breaks the legacy stacked pattern that docs-theme-extras.css:40 currently defends:
.dark .reuse-image-nodark:has(+ .toggle-light) { display: none; }
That rule exists because a lone reuse-image followed by a sibling reuse-image-dark for the same figure would otherwise stack two images in dark mode. It works by keying on the .reuse-image-nodark wrapper class that only the SINGLE branch emits.
If the SINGLE branch starts auto-resolving a dark file, those sites flip to the PAIR branch. The wrapper becomes .toggle-dark, the :has() guard no longer matches, and the sibling reuse-image-dark still emits its own .toggle-light figure, so dark mode renders two dark images. A Hugo shortcode cannot see whether a reuse-image-dark follows it, which is precisely why the current guard lives in CSS rather than in the template, so there is no in-template way to make auto-discovery conditional on the absence of that sibling.
In other words, the legacy pattern and convention-based dark resolution are mutually exclusive. The legacy sites have to go first.
Consumer survey
Scanned for lone reuse-image src= calls with no srcDark, excluding public/, resources/, node_modules/, and any nested worktree or clone directory.
| Repo | Commit | Lone calls | Legacy stacked pairs | Stranded -dark asset in canonical content |
|---|---|---|---|---|
| kgateway-oss | 8abb1a4c |
114 | 62 | 0 |
| agentgateway-oss-website | 98223d2a |
416 | 0 | 0 |
| docs | bd1868b97 |
193 | 6 | 0 |
Two things this shows:
- Auto-discovery would be a no-op in agentgateway and near-enough in the hub. Zero stranded dark assets means the convention is already airtight in canonical content: wherever a
-darkfile exists, the page references it. Nothing would change rendering. - kgateway carries the whole cost. 62 of the 68 legacy pairs across all three consumers are in kgateway-oss.
Every "stranded" hit in an early pass turned out to be inside .claude/worktrees/ or .oss-clones/, so they are duplicates of content already counted, not additional sites.
Scoping: the kgateway-oss migration
62 pairs across 36 files, 26 of them under assets/kgw-docs/ where one edit serves every version.
The transform is fully mechanical. Across all 62 pairs:
- 0 have any attribute divergence between the two calls. Where one carries
width,alt, orcaption, so does the other, identically. - 0 have a blank line between the two calls, so the two are always adjacent lines.
- Extensions split 32
.svg/ 30.png, which makes no difference to the transform.
Two classes, and they get opposite treatment:
Class 1: 46 pairs where srcDark points at the same file as src
The dark call is a pure no-op duplicate. 45 of the 46 have no -dark asset on disk at all, so there is no dark variant to preserve.
Migration: delete the reuse-image-dark line. No srcDark is added. The lone reuse-image already renders in both modes via the SINGLE branch, which is the correct end state, and it is what the page effectively shows today anyway.
Class 2: 16 pairs where srcDark points at a distinct, real file
All 16 dark assets exist. Migration: merge into srcDark= on the first call, delete the second.
| File | Light | Dark |
|---|---|---|
assets/kgw-docs/pages/about/architecture.md:7 |
gw-control-plane-components.svg |
…-dark.svg |
assets/kgw-docs/pages/about/architecture.md:43 |
translation-loop.svg |
…-dark.svg |
assets/kgw-docs/pages/integrations/istio/sidecar/ingress.md:23 |
sidecar-ingress.svg |
…-dark.svg |
assets/kgw-docs/pages/setup/listeners/sni.md:13 |
sni-listener.svg |
…-dark.svg |
assets/kgw-docs/snippets/cr-ov.md:3 |
kgw-crs-light.svg |
kgw-crs-dark.svg |
assets/kgw-docs/pages/traffic-management/route-delegation/basic.md:7 |
route-delegation-basic.svg |
…-dark.svg |
assets/kgw-docs/pages/traffic-management/route-delegation/label.md:10 |
route-delegation-labels.svg |
…-dark.svg |
assets/kgw-docs/pages/traffic-management/route-delegation/label.md:31 |
route-delegation-labels-wildcard.svg |
…-dark.svg |
assets/kgw-docs/pages/traffic-management/route-delegation/multi-parent.md:7 |
route-delegation-multi-parent.svg |
…-dark.svg |
assets/kgw-docs/pages/traffic-management/route-delegation/multi-level-delegation.md:7 |
route-delegation-multi-level.svg |
…-dark.svg |
assets/kgw-docs/pages/traffic-management/route-delegation/header-query.md:11 |
route-delegation-header-query.svg |
…-dark.svg |
assets/kgw-docs/pages/traffic-management/route-delegation/inheritance/kgateway-policies.md:16 |
route-delegation-inheritance-kgateway.svg |
…-dark.svg |
assets/kgw-docs/pages/traffic-management/route-delegation/inheritance/native-policies.md:16 |
route-delegation-inheritance-native.svg |
…-dark.svg |
content/docs/envoy/latest/setup/listeners/sni.md:18 |
sni-listener.svg |
…-dark.svg |
content/docs/envoy/2.3.x/setup/listeners/sni.md:18 |
sni-listener.svg |
…-dark.svg |
content/docs/envoy/main/setup/listeners/sni.md:18 |
sni-listener.svg |
…-dark.svg |
sni-listener.svg appears four times because the three versioned content/docs/envoy/* copies duplicate the shared assets/kgw-docs/pages/setup/listeners/sni.md snippet. Worth checking whether the versioned copies can be replaced by a reuse of the snippet as part of this.
One content bug found while scoping
assets/kgw-docs/pages/about/deployment-patterns.md:73 renders img/sidecar-ingress.svg and points srcDark at the same light file, while assets/kgw-docs/pages/integrations/istio/sidecar/ingress.md:23 pairs that same diagram correctly with img/sidecar-ingress-dark.svg. The dark diagram exists and that page does not use it. This is worth fixing regardless of what happens to the shortcode.
Note for anyone re-running a scan: a <stem>-dark.<ext> heuristic undercounts, because cr-ov.md uses a -light/-dark suffix pair (kgw-crs-light.svg / kgw-crs-dark.svg) rather than a bare stem plus -dark. My first pass reported 15 of 16 dark assets present for that reason; the real figure is 16 of 16.
Proposed sequence
- Migrate kgateway-oss. 36 files, two mechanical classes as above, plus the
deployment-patterns.mdfix. Scriptable, but the diff should be eyeballed in both modes because class 1 deletes lines. - Migrate the 6 legacy pairs in solo-io/docs. Not yet broken out by class in this issue.
- Delete the
.reuse-image-nodarkguard fromdocs-theme-extras.css:40and the SINGLE branch's wrapper class, once no consumer relies on it. That removal is the actual prize here: the guard is a CSS workaround for an authoring pattern nothing would still use. - Then decide on auto-discovery in the SINGLE branch, which by that point has no pattern left to collide with.
Open question on step 4
Even with the legacy pattern gone, auto-discovery makes srcDark redundant on the happy path but changes the meaning of a lone reuse-image from "show this in both modes" to "show this, or its dark sibling if one happens to exist on disk". That is action-at-a-distance: adding an asset changes how an untouched page renders. The alternative is to keep srcDark explicit and instead add a build-time check that fails when a -dark asset exists on disk and no page references it, which would have caught agentgateway/website#999 without changing any rendering semantics.
I lean toward the lint rather than the auto-discovery, on the grounds that the version-override convention is safe because a version directory is unambiguous about intent, whereas a -dark file sitting next to its light counterpart is not.
Scanned at docs-theme-extras 8058485.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with reuse-image.html, utils/resolve-versioned-image.html, and docs-theme-extras.css:40, then review the listed kgateway and docs content files. Confirm the legacy pairs and the deployment-patterns.md dark-image bug, inspect both rendering modes, and resolve whether the final change should be dark-file auto-discovery or a build-time check after migration.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, html, markdown
- Domain
- documentation, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100