Skip to content

fix(flow-server): add support for AppShell stylesheets in service worker precache - #25047

Open
platosha wants to merge 7 commits into
mainfrom
fix/offline-stylesheet
Open

fix(flow-server): add support for AppShell stylesheets in service worker precache#25047
platosha wants to merge 7 commits into
mainfrom
fix/offline-stylesheet

Conversation

@platosha

@platosha platosha commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Fixes vaadin/hilla#5806

Summary

Stylesheets declared via @StyleSheet on an AppShellConfigurator are now included in the PWA service worker's precache, so they are available offline.

Feature

  • PwaRegistry now enumerates AppShell stylesheets via AppShellRegistry.getStyleSheets(...) and adds each to self.additionalManifestEntries in the generated sw-runtime.js.
  • Paths are normalized (leading ./, /, context://, base:// stripped) so precache entries resolve relative to the service-worker scope. External http(s):// URLs are passed through.

Refactors in AppShellRegistry

  • Extracted stylesheet collection into a dedicated getStyleSheets(VaadinService) method, reused by both createSettings and the new PwaRegistry precache path.
  • Content-hash query parameter is now appended inside resolveStyleSheetHref (production mode only). addStyleSheets no longer branches between dev and production for URL rewriting.
  • addStyleSheets now takes a List<String> of raw annotation values instead of a Map<String, String> of pre-resolved hrefs — resolution happens once per sheet at emit time.
  • Dev-mode data-file-path / data-id attributes now carry the raw @StyleSheet annotation value (previously stripped of prefixes). This lets StyleSheetHotswapper match on the same string it emits when a stylesheet is hot-swapped. In production these attributes are omitted entirely.

platosha added 6 commits July 24, 2026 20:49
…ker precache

Fixes vaadin/hilla#5806

- Add `AppShellRegistry.getStyleSheets` to fetch stylesheets defined by `@StyleSheet`.
- Normalize stylesheet URIs for context-root-relative resolution before caching.
- Update service worker runtime JS in `PwaRegistry` to add app shell stylesheets to the offline page cache.
- Refactor `AppShellRegistry.createSettings`:
  - Extract stylesheet collection logic into a dedicated method.
  - Remove duplication between dev and production mode handling.
  - Simplify attribute mapping for hot-swapping in development builds.
…mode

- Remove `data-file-path` assertions for all stylesheet types in production mode, as the attribute is not used when serving hashed resources.
- Normalize expected `data-file-path` values in dev mode tests to reflect that paths are preserved (including leading `/` or `context://` prefix) rather than stripped.
- Add comprehensive test cases for hotswap behavior with absolute, relative, and context-path stylesheet annotations to verify correct removal and refresh strategy.
@platosha
platosha force-pushed the fix/offline-stylesheet branch from 7bc8fef to afcc0de Compare July 24, 2026 17:49
@platosha platosha changed the title fix/offline stylesheet fix(flow-server): add support for AppShell stylesheets in service worker precache Jul 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Test Results

 1 441 files  ±0   1 441 suites  ±0   1h 39m 20s ⏱️ + 1m 13s
10 309 tests +3  10 239 ✅ ±0  67 💤 ±0  2 ❌ +2  1 🔥 +1 
10 763 runs  +3  10 692 ✅ ±0  68 💤 ±0  2 ❌ +2  1 🔥 +1 

For more details on these failures and errors, see this check.

Results for commit 3c39ed8. ± Comparison against base commit 626a502.

Comment on lines +299 to +303
} else if (uri.startsWith(CONTEXT_PROTOCOL_PREFIX)) {
uri = uri.substring(CONTEXT_PROTOCOL_PREFIX.length());
} else if (uri.startsWith(BASE_PROTOCOL_PREFIX)) {
uri = uri.substring(BASE_PROTOCOL_PREFIX.length());
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

context://a.css and base://a.css resolves to different resources if a servlet mapping is in use. Just stripping the prefix might produce wrong results.

.getStyleSheets(VaadinService.getCurrent())) {
String uri = FrontendDependencyUrlResolver
.resolveToContextRoot(styleSheet);
if (uri == null) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Absolute URLs (starting with http://, https:// or //) should probably be skipped as well

} else if (uri.startsWith(BASE_PROTOCOL_PREFIX)) {
uri = uri.substring(BASE_PROTOCOL_PREFIX.length());
}
filesToCache.add(offlinePageCache(uri));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

offlinePageCache uses the offlineHtml hashcode as revision, so if you only update the CSS and rebuild the application, the revision will not change, and a stale stylesheet may be used.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also, in production stylesheets URL gets the v-c content hash appended to it, so I guess this will bypass the workbox cache.
I'm not sure if the workobx entry URL should contain the parameter or if we should tune the ignoreURLParametersMatching setting.

Comment on lines +265 to 270
var styleSheets = getStyleSheets(request.getService());
if (!request.getService().getDeploymentConfiguration()
.isProductionMode()) {
ActiveStyleSheetTracker.get(request.getService())
.trackForAppShell(stylesheets.values());
.trackForAppShell(styleSheets);
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The previous code used resolveStyleSheetHref(sheet.value(), request) to process stylesheet and filtered out null/blank results. The getStyleSheets(request.getService()) call does not use resolveStyleSheetHref at all. Is this on purpose? I wonder if trackForAppShell receives values that should not be considered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: 🔎Iteration reviews

Development

Successfully merging this pull request may close these issues.

Missing styles when offline

3 participants