Skip to content

feat(angular): resolve @xplat-images from the shared xplat assets - #876

Merged
ChronosSF merged 2 commits into
vnextfrom
feat/xplat-image-fallback
Sep 30, 2026
Merged

ChronosSF merged 2 commits into
vnextfrom
feat/xplat-image-fallback

Conversation

@ChronosSF

@ChronosSF ChronosSF commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

Follow-up to the discussion on #547 — the underlying reason JP image breakage keeps recurring.

Problem

Topics generated from the xplat source import their images as @xplat-images/<path>. The two sites resolved that differently:

config target
docs/xplat/astro.config.ts src/assets/images — one shared, language-agnostic folder
docs/angular/astro.config.ts src/content/<lang>/images — per locale

And sync-generated.mjs copies MDX only. So every xplat topic synced into Angular needed its images copied into the Angular tree twice, once per language, by hand. Nothing enforced it, so it was found by deploys instead: carousel (#873), and switch and avatar before it.

Worth being precise about what #547 does and doesn't do here: it stops content being copied into the Angular tree, but leaves the alias untouched. A bare-specifier Vite alias maps to a fixed absolute path regardless of where the importing file sits, so reading generated MDX in place doesn't change image resolution. This is the asset-shaped half of the same thesis.

Change

Replace the alias with a pre plugin that searches roots in order:

  1. docs/angular/src/content/<lang>/images — the locale's own directory
  2. docs/xplat/src/assets/images — the shared xplat assets

First hit wins. A resolve.alias cannot express a fallback, which is why this is a plugin rather than a second alias entry.

Precedence is unchanged wherever a copy already exists, so this is not a content change — it only stops a missing copy from being fatal. Dropping a file at the same relative path under the locale's directory still overrides the shared one, so localized screenshots remain possible.

A specifier that matches nothing resolves to the shared root, so the resulting ImageNotFound names where a new shared image belongs rather than a per-locale path most images should never need.

Verification

Against vnext, which lacks the nine JP carousel images:

  • angular:build:jp — passes, where today it fails with ImageNotFound.
  • angular:build:en — passes.
  • Instrumented the resolver and ran a full JP build: 41 specifiers resolved from the Angular locale directory (existing copies still win), 9 from the shared folder, 0 unresolved. Those 9 are exactly the images fix(jp/angular): complete the carousel xplat sync for Japanese #873 adds by hand.

How this relates to #873

#873 should still merge — it also repoints the JP TOC and deletes the superseded native topic, which this does not address, and it is green and unblocks the failing deploy now. Once both are in, the nine images it adds become redundant duplicates: harmless, they simply keep winning precedence.

Follow-up: #877

Tracked in #877, to be handled immediately after this lands. 361 of the images duplicated into the Angular tree become removable once this resolver is in — but deliberately not "all the identical ones": 155 of the 516 checksum-identical copies have to stay, because tracked Angular topics reference them by relative path rather than through the alias, and deleting those would break the pages. #877 carries the measured breakdown and the method.

🤖 Generated with Claude Code

Topics generated from the xplat source import their images as
'@xplat-images/<path>'. docs/xplat/astro.config.ts resolves that to one
shared, language-agnostic folder, but docs/angular/astro.config.ts resolved
it per locale, to src/content/<lang>/images — and sync-generated.mjs copies
MDX only. So every xplat topic synced into Angular needed its images copied
into the Angular tree twice, once per language, by hand.

Nothing enforced that, so it was found by deploys: carousel (#873), and
switch and avatar before it.

Replace the alias with a pre plugin that searches the Angular locale's image
directory first and the shared xplat folder second. An alias cannot express a
fallback, hence the plugin. Precedence is unchanged where a copy already
exists, so this is not a content change; it only stops a missing copy from
being fatal.

Verified against vnext, which lacks the nine JP carousel images:

- angular:build:jp passes where it previously failed with ImageNotFound
- angular:build:en passes
- instrumenting the resolver over a full JP build: 41 specifiers resolve from
  the Angular locale dir (existing copies still win), 9 from the shared
  folder, 0 unresolved. Those 9 are exactly the images #873 adds by hand.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@dobromirts

Copy link
Copy Markdown
Contributor
  • EN: all 170 referenced images exist in the Angular folder and are same to the shared ones.
  • JP: 149 identical copies, 19 fallbacks to the shared folder and 2 NuGet screenshots intentionally differ.

Result based on local test:
From repo root npm run build:jp --prefix docs/angular npm run build:en --prefix docs/angular

New .png in docs/xplat/src/assets/images/.
image
Result:
image
image

@ChronosSF
ChronosSF merged commit 57c6d1d into vnext Sep 30, 2026
8 checks passed
@ChronosSF
ChronosSF deleted the feat/xplat-image-fallback branch September 30, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants