I just moved the Angular front end over to hybrid rendering - Angular prerenders the blog post pages and a handful of static routes at build time, so search engines and social-link crawlers get real HTML instead of an empty SPA shell that only fills in after the JS bundle runs. Everything else (search, tag filtering, the admin panel) still renders client-side, same as before.

That broke the fallback rule from the last revision of this config:

RewriteRule ^(.*)$ %{ENV:BASE}index.html [NC,L]

Before, index.html was always the same neutral SPA shell no matter what route hit it - Angular's router figured out the rest client-side. Now that the build prerenders content at /, index.html is the baked-in home page. Hit /admin/posts on a cold load and Apache would happily serve you the home page's markup instead of a blank shell, and Angular would have to tear it down and re-render before the admin page showed up.

The fix is Angular's own convention for this: alongside every prerendered route's index.html, the build also emits a neutral index.csr.html specifically for this fallback case. Point the rewrite at that instead:

RewriteRule ^(.*)$ %{ENV:BASE}index.csr.html [NC,L]

One more spot needed the same file added - the no-cache header rule that already covered index.html so a stale reference to a deleted asset hash never survives a deploy:

<FilesMatch "^(index\.html|index\.csr\.html|manifest\.webmanifest|ngsw\.json|ngsw-worker\.js|safety-worker\.js|worker-basic\.min\.js)$">
    Header set Cache-Control "no-cache"
</FilesMatch>

Prerendered routes still resolve correctly without touching this rule at all - rule #1 in the <Directory> block already serves any request matching a real file or directory as-is, and now /post/16/... really is one, so it never falls through to the rewrite in the first place.