This repo contains a small example demonstrating an apparent issue in Firefox's handling of full page "Reload" actions on an SPA performing only replaceState
operations after loading initially via a 301 redirect.
The issue as described is present in the now-current version of Firefox, 67.0.2.
-
Build the provided Docker image to serve the static files demonstrating the issue:
docker build -t firefox-redirect-history-issue-sample .
-
Run the image in an interactive container with request logs visible (this example runs on port 3000):
docker run -it -p 3000:80 firefox-redirect-history-issue-sample
- Open Firefox
- Open the root page of the sample container (
http://localhost:3000
if using the commands above) - Click the "Redirect to /page1" link
- Wait for
/page1
to load - Wait 3 seconds for the transition to
/page2
(viahistory.replaceState
) - Wait 3 seconds for the transition to
/page3
(viahistory.replaceState
) - On
/page3
, press the "Reload current page" button (or its keyboard shortcut) to reload/page3
- The browser makes a
GET
request to{server}/page3
- The browser logs a console message
Navigated to {server}/page3
- The address bar remains at
/page3
window.location.pathname
remains/page3
when the JavaScript loads, and/page3
content is displayed
- The browser makes a
GET
request to{server}/page3
(as expected) - The browser logs a console message
Navigated to {server}/page3
(as expected) - The address bar changes to
/page1
(not expected) window.location.pathname
is set to/page1
when the JavaScript loads, causing the entire sequence of transitions to occur; i.e./page1
to/page2
to/page3
(not expected)
- If a call to
pushState
is introduced at any point in the history chain (between/page1
and/page2
, or between/page2
and/page3
), the issue no longer occurs and/page3
reloads as expected- If only the transition between
/page2
and/page3
is changed topushState
, reloading the page when it is on/page2
(before getting to/page3
) results in the problematic behavior and starts over at/page1
-- only if we make it to/page3
does the issue go away
- If only the transition between
- Selecting the
/page3
URL in the address bar and hitting enter (to submit the request) results in a server request for/page3
and, unlike the reload operation, will not roll back the location history to/page1
.- The location remains
/page3
as expected. At this point, subsequent page reload operations via the browser button orlocation.reload()
will work as expected.
- The location remains
- Chrome and Safari (desktop) do not exhibit the behavior described above and always reload
/page3
directly