diff options
author | 2023-12-14 10:20:56 -0500 | |
---|---|---|
committer | 2023-12-14 10:20:56 -0500 | |
commit | 151bd429b11a73d236ca8f43e8f5072e7c29641e (patch) | |
tree | 3760d24c792a0460662c8da6c2138bf792e2fb42 | |
parent | 242fd71a6a98512586d06adafd57446cb46e5370 (diff) | |
download | astro-151bd429b11a73d236ca8f43e8f5072e7c29641e.tar.gz astro-151bd429b11a73d236ca8f43e8f5072e7c29641e.tar.zst astro-151bd429b11a73d236ca8f43e8f5072e7c29641e.zip |
Prevent Partytown from hijacking history API (#9419)
* Partytown overrides these methods to... do things, but it breaks ViewTransitions in Firefox.
* Only redefine pushstate/replacestate in the browser
-rw-r--r-- | .changeset/angry-avocados-live.md | 5 | ||||
-rw-r--r-- | packages/astro/src/transitions/router.ts | 16 |
2 files changed, 16 insertions, 5 deletions
diff --git a/.changeset/angry-avocados-live.md b/.changeset/angry-avocados-live.md new file mode 100644 index 000000000..c48db5948 --- /dev/null +++ b/.changeset/angry-avocados-live.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Prevent Partytown from hijacking history APIs diff --git a/packages/astro/src/transitions/router.ts b/packages/astro/src/transitions/router.ts index ce92fd630..b2cfbca6a 100644 --- a/packages/astro/src/transitions/router.ts +++ b/packages/astro/src/transitions/router.ts @@ -9,15 +9,21 @@ type State = { }; type Events = 'astro:page-load' | 'astro:after-swap'; +// Create bound versions of pushState/replaceState so that Partytown doesn't hijack them, +// which breaks Firefox. +const inBrowser = import.meta.env.SSR === false; +const pushState = (inBrowser && history.pushState.bind(history)) as typeof history.pushState; +const replaceState = (inBrowser && history.replaceState.bind(history)) as typeof history.replaceState; + // only update history entries that are managed by us // leave other entries alone and do not accidently add state. export const updateScrollPosition = (positions: { scrollX: number; scrollY: number }) => { if (history.state) { history.scrollRestoration = 'manual'; - history.replaceState({ ...history.state, ...positions }, ''); + replaceState({ ...history.state, ...positions }, ''); } }; -const inBrowser = import.meta.env.SSR === false; + export const supportsViewTransitions = inBrowser && !!document.startViewTransition; @@ -79,7 +85,7 @@ if (inBrowser) { } else if (transitionEnabledOnThisPage()) { // This page is loaded from the browser addressbar or via a link from extern, // it needs a state in the history - history.replaceState({ index: currentHistoryIndex, scrollX, scrollY }, ''); + replaceState({ index: currentHistoryIndex, scrollX, scrollY }, ''); history.scrollRestoration = 'manual'; } } @@ -170,7 +176,7 @@ const moveToLocation = (to: URL, from: URL, options: Options, historyState?: Sta if (to.href !== location.href && !historyState) { if (options.history === 'replace') { const current = history.state; - history.replaceState( + replaceState( { ...options.state, index: current.index, @@ -181,7 +187,7 @@ const moveToLocation = (to: URL, from: URL, options: Options, historyState?: Sta to.href ); } else { - history.pushState( + pushState( { ...options.state, index: ++currentHistoryIndex, scrollX: 0, scrollY: 0 }, '', to.href |