Skip to content

[BUGFIX] Rebuild inline SVG sprite for cached pages when asset cache is lost - #44

Closed
davidsteeb wants to merge 1 commit into
mainfrom
bugfix/self-healing-inline-svg-sprite
Closed

[BUGFIX] Rebuild inline SVG sprite for cached pages when asset cache is lost#44
davidsteeb wants to merge 1 commit into
mainfrom
bugfix/self-healing-inline-svg-sprite

Conversation

@davidsteeb

Copy link
Copy Markdown
Contributor

Problem

The inline SVG sprite is injected by InlineSvgInjector, which reads the collected SVG files from the tx_assetcollector cache. That cache is separate from the page cache and may even sit on a different backend (e.g. page cache on Redis, tx_assetcollector on the default DB backend).

When the two desync — the asset cache is cleared (or evicted) while the page cache survives — a fully cached page is delivered without the ViewHelpers being re-rendered, so the collector is empty and the sprite is omitted. Result: every icon on the page disappears until the page cache is regenerated. This shows up as “icons missing on the first load(s) after clearing the cache”.

Fix

InlineSvgInjector now scans the response body for referenced icons (<use href="#icon-…">) and re-resolves any that are not collected from an icon registry:

  • The registry (icon identifier => SVG file) is built from TypoScript (plugin.tx_assetcollector.icons) while it is available, and persisted in a dedicated cache in the system group — so it survives a pages cache flush and is available to rebuild the sprite in cached frontend scope, where TypoScript is gone.
  • It is read lazily — only when the page actually references an uncollected icon — so regular requests pay nothing.
  • An empty registry makes the self-heal a no-op, so it can never make rendering worse than before.

Also makes AssetCollector::loadTypoScript() tolerant of cached frontend scope, where FrontendTypoScript::getSetupArray() throws ("Setup array has not been initialized…").

Tests

  • Unit: addReferencedIcons() resolves a missing referenced icon from the registry, is a no-op (and does not even invoke the registry provider) when the icon is already collected, and ignores unknown icons.
  • Functional: SvgViewHelperSelfHealTest reproduces the desync (page cache kept, tx_assetcollector cache flushed) and asserts the cached page is still delivered with the full sprite.

All existing unit + functional tests pass; php-cs-fixer and phpstan (repo configs) are clean.

🤖 Generated with Claude Code

…is lost

The inline SVG sprite is injected by InlineSvgInjector, which reads the
collected SVG files from the "tx_assetcollector" cache. That cache lives
separately from the page cache and may even sit on a different backend.
When the two desync - e.g. the asset cache is cleared (or evicted) while
the page cache survives - a fully cached page is delivered without the
ViewHelpers being re-rendered, the collector ends up empty and the sprite
is omitted: every icon on the page disappears until the page cache is
regenerated.

The middleware now scans the response for referenced icons
(<use href="#icon-...">) and re-resolves any that are not collected from
an icon registry. The registry (icon identifier => SVG file) is built from
TypoScript while it is available and persisted in a dedicated cache in the
"system" group, so it survives a "pages" cache flush and is available to
rebuild the sprite in cached frontend scope, where TypoScript is gone. It
is read lazily - only when the page actually references an uncollected
icon - so regular requests are not slowed down.

Also makes AssetCollector::loadTypoScript() tolerant of cached frontend
scope, where FrontendTypoScript::getSetupArray() throws.
@davidsteeb
davidsteeb requested a review from bmack June 12, 2026 21:40
@bmack
bmack requested a review from achimfritz June 13, 2026 05:43

@achimfritz achimfritz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👎
this looks like a workaround for me, how can this occurre?
the asset cache has the same tags as the page-cache.
(btw. you can put the asset-cache into the same backend as the page-cache, i have already done so)

@achimfritz

Copy link
Copy Markdown
Contributor

not this extension scope.

@achimfritz achimfritz closed this Aug 4, 2026
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