Skip to content

fix: emit servlet-relative href for AppShell @StyleSheet (#24233) (CP: 25.1)#24245

Merged
vaadin-bot merged 1 commit into25.1from
cherry-pick-24233-to-25.1-1777884725473
May 4, 2026
Merged

fix: emit servlet-relative href for AppShell @StyleSheet (#24233) (CP: 25.1)#24245
vaadin-bot merged 1 commit into25.1from
cherry-pick-24233-to-25.1-1777884725473

Conversation

@vaadin-bot
Copy link
Copy Markdown
Collaborator

This PR cherry-picks changes from the original PR #24233 to branch 25.1.

Original PR description

AppShellRegistry.resolveStyleSheetHref expanded context://-prefixed @Stylesheet values server-side using request.getContextPath() + "/", producing absolute server paths like that get baked into index.html. This breaks behind reverse proxies that don't preserve the servlet container's context path in the public URL: the server emits /foo/styles.css but the browser fetches it from the public host where /foo/ doesn't exist.

Use service.getContextRootRelativePath(request) instead — the same servlet-relative path (./, ../, etc.) that the bootstrap callback populates into CONTEXT_ROOT_URL for the UIDL path. The resulting href is resolved by the browser against , which Vaadin sets from the actual request URL (honoring X-Forwarded-* headers).

This brings AppShell-level @Stylesheet resolution in line with the component-level UIDL path, which already used the relative form via the client-side URIResolver.

Test fixtures updated to reflect the new servlet-relative hrefs. AppShellRegistryAuraAutoLoadTest had a Mockito mock that returned null for getContextRootRelativePath; it now stubs "./".

Related to #24218.

AppShellRegistry.resolveStyleSheetHref expanded context://-prefixed
@Stylesheet values server-side using request.getContextPath() + "/",
producing absolute server paths like <link href="/foo/styles.css"> that
get baked into index.html. This breaks behind reverse proxies that don't
preserve the servlet container's context path in the public URL: the
server emits /foo/styles.css but the browser fetches it from the public
host where /foo/ doesn't exist.

Use service.getContextRootRelativePath(request) instead — the same
servlet-relative path (./, ../, etc.) that the bootstrap callback
populates into CONTEXT_ROOT_URL for the UIDL path. The resulting href is
resolved by the browser against <base>, which Vaadin sets from the
actual request URL (honoring X-Forwarded-* headers).

This brings AppShell-level @Stylesheet resolution in line with the
component-level UIDL path, which already used the relative form via the
client-side URIResolver.

Test fixtures updated to reflect the new servlet-relative hrefs.
AppShellRegistryAuraAutoLoadTest had a Mockito mock that returned null
for getContextRootRelativePath; it now stubs "./".

Related to #24218.
@github-actions github-actions Bot added the +0.0.1 label May 4, 2026
@vaadin-bot
Copy link
Copy Markdown
Collaborator Author

This PR is eligible for auto-merging policy, so it has been approved automatically. If there are pending conditions, auto merge (with 'squash' method) has been enabled for this PR [Message is sent from bot]

@vaadin-bot vaadin-bot enabled auto-merge (squash) May 4, 2026 09:01
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 4, 2026

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

Test Results

 1 387 files  ±0   1 387 suites  ±0   1h 19m 30s ⏱️ +48s
10 017 tests +1   9 947 ✅ +1  70 💤 ±0  0 ❌ ±0 
10 490 runs  +1  10 411 ✅ +1  79 💤 ±0  0 ❌ ±0 

Results for commit 728a3a7. ± Comparison against base commit f35fe9c.

@vaadin-bot vaadin-bot merged commit 3bf9f2d into 25.1 May 4, 2026
29 checks passed
@vaadin-bot vaadin-bot deleted the cherry-pick-24233-to-25.1-1777884725473 branch May 4, 2026 09:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants