`request.url` mismatch when app is loaded in iframe using storage access headers

Open
#13,622 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
react, typescript, vite
Domain
backend, web-dev

Research direction

Start with the linked reproduction's README.md and run npm install followed by npm run incorrect, using /public/iframe.html and Chrome's third-party-cookie phaseout flag. Compare window.location.href with the loader's request.url after granting storage access and reloading; done means request.url matches the iframe URL and does not expose the parent frame's hostname.

Written by the indexing model from the issue text.

Description

bug pkg:react-router
I'm using React Router as a...

framework

Reproduction

Go to https://github.com/mrksbnch/react-router-storage-access-headers and follow the steps in the README.md, or refer to the instructions below.
To test this, open the application in Chrome and enable the following flag:
chrome://flags/#test-third-party-cookie-phaseout.

  1. Run npm install to install dependencies.
  2. Run npm run incorrect to start the app at http://localhost:3000 and serve a static iframe.html file located at /public/iframe.html via http://localhost:4000.
  3. Open the iframe at http://localhost:4000.
  4. Grant storage access by clicking the button inside the iframe.
  5. You should see the URL from both window.location.href and request.url (exposed via the loader); these should be identical.
  6. Reload the page.

As background information, this article about Storage Access Headers explains the use cases and how the mechanism works.

The main use case is allowing your app to be loaded inside an iframe.
This typically comes with certain limitations (especially with cookies) which are treated as third-party cookies.
Most browsers already block third-party cookies, and Chrome is following the same path.

There are a few workarounds to these limitations, such as using partitioned cookies or the Storage Access API.
The Storage Access API allows an application to access the same cookies available outside of an iframe (assuming the user has granted access).

In the past, requesting storage access was only possible on the client side, even if the user had already granted access. With Storage Access Headers, it's now possible to request storage access on the server side, assuming that the user has granted access (on the client) once before.

System Info
System:
    OS: macOS 14.6.1
    CPU: (8) arm64 Apple M1
    Memory: 117.17 MB / 8.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 23.7.0 - /opt/homebrew/bin/node
    npm: 10.9.2 - /opt/homebrew/bin/npm
    pnpm: 9.15.0 - ~/Library/pnpm/pnpm
  Browsers:
    Chrome: 136.0.7103.114
    Safari: 17.6
  npmPackages:
    @react-router/dev: ^7.6.0 => 7.6.0 
    @react-router/node: ^7.6.0 => 7.6.0 
    @react-router/serve: ^7.6.0 => 7.6.0 
    react-router: ^7.6.0 => 7.6.0 
    vite: ^6.3.3 => 6.3.5
Used Package Manager

npm

Expected Behavior

The URLs shown in the demo application (window.location.href and request.url (from the loader)) should be the same.

Even when the page is loaded inside an iframe, the server-side URL should not reflect or expose the parent frame’s URL.

Actual Behavior

The URL from the loader (request.url) incorrectly shows the URL of the parent page.
It appears that the React Router dev server sets the URL incorrectly in this case.

Note:

  • The HTTP Host header is correctly set to the actual application’s domain.
  • In the demo, the path is /. If the page was served at a different path, e.g., /page, request.url would still report the hostname of the parent page but show the correct path from the iframe.

I'm not sure if there are any workarounds when using the React Router dev server. It might work correctly with a custom Express server because my Express-based example (linked in the repo) behaves as expected.

Dominant language
TypeScript
Stars
56.6k
Forks
10.9k
Avg merge
3d 9h
Merged PRs (30d)
39

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from remix-run/react-router

All issues in remix-run/react-router

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.