Skip to content

fix(web): emit manifest link with crossorigin=use-credentials for credential-gated proxies#2054

Open
codebanditssss wants to merge 2 commits into
AgentWrapper:mainfrom
codebanditssss:fix/manifest-crossorigin
Open

fix(web): emit manifest link with crossorigin=use-credentials for credential-gated proxies#2054
codebanditssss wants to merge 2 commits into
AgentWrapper:mainfrom
codebanditssss:fix/manifest-crossorigin

Conversation

@codebanditssss
Copy link
Copy Markdown

closes #2008

problem: when running the dashboard behind credential-gated reverse proxies (like cloudflare access or oauth2-proxy), same-origin manifest fetches omit credentials by default, leading to cors errors and blocking the pwa manifest from loading.

solution:

extract manifest builder as a pure function in pwa-manifest.ts
serve the manifest JSON via a route handler in manifest.webmanifest/route.ts
delete manifest.ts to stop next.js auto-emitting a link tag without crossorigin
emit the manifest link manually in layout.tsx with crossOrigin="use-credentials"

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 24, 2026

Greptile Summary

This PR fixes PWA manifest loading failures behind credential-gated reverse proxies (e.g., Cloudflare Access, oauth2-proxy) by replacing Next.js's auto-generated manifest link (which omits credentials) with a manually emitted link carrying crossOrigin="use-credentials".

  • manifest.ts is extracted into src/lib/pwa-manifest.ts as a pure named export, and a new route handler at manifest.webmanifest/route.ts serves the manifest JSON with explicit Content-Type and Cache-Control headers.
  • The root layout manually injects <link rel="manifest" crossOrigin="use-credentials">, bypassing Next.js's automatic (credentials-free) manifest link injection; the test is updated to match the refactored import path.

Confidence Score: 5/5

Safe to merge — the change is a targeted, well-scoped fix with no altered business logic and a passing test covering the manifest content.

The manifest builder logic is unchanged; only the delivery mechanism and link emission are restructured. The route handler is server-side only, the crossOrigin=use-credentials attribute is correct for same-origin credential-gated fetches, and deleting app/manifest.ts cleanly removes the competing auto-injected link tag. No dynamic data paths are affected.

No files require special attention.

Important Files Changed

Filename Overview
packages/web/src/app/layout.tsx Manually adds <link rel="manifest" crossOrigin="use-credentials"> inside a <head> block; since manifest.ts is deleted, no duplicate manifest link is emitted by Next.js.
packages/web/src/app/manifest.webmanifest/route.ts New GET route handler serving the PWA manifest JSON with Content-Type: application/manifest+json and Cache-Control: public, max-age=0, must-revalidate; dynamically rendered on each request.
packages/web/src/lib/pwa-manifest.ts Renamed from app/manifest.ts, converted from a default export to a named export buildPwaManifest(); logic is unchanged.
packages/web/src/app/manifest.test.ts Test updated to import buildPwaManifest from the new @/lib/pwa-manifest path; assertions are identical to before.

Sequence Diagram

sequenceDiagram
    participant Browser
    participant Proxy as Credential-Gated Proxy
    participant Next as Next.js Server

    Browser->>Browser: "Parse HTML, find link rel=manifest crossorigin=use-credentials"
    Browser->>Proxy: GET /manifest.webmanifest with cookies/auth headers
    Proxy->>Next: Forward request after verifying credentials
    Next->>Next: buildPwaManifest via route handler
    Next-->>Proxy: 200 application/manifest+json
    Proxy-->>Browser: 200 manifest JSON
    Browser->>Browser: PWA install prompt available
Loading

Reviews (2): Last reviewed commit: "chore(web): add cache-control header to ..." | Re-trigger Greptile

Comment thread packages/web/src/app/manifest.webmanifest/route.ts
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.

Manifest <link> emits without crossorigin, breaking deployments behind credential-gated reverse proxies

1 participant