@@ -274,30 +274,54 @@ const { fallback = 'animate' } = Astro.props as Props;
274
274
// that is going to another page within the same origin. Basically it determines
275
275
// same-origin navigation, but omits special key combos for new tabs, etc.
276
276
if (
277
- link &&
278
- link instanceof HTMLAnchorElement &&
279
- link.href &&
280
- (!link.target || link.target === '_self') &&
281
- link.origin === location.origin &&
282
- !(
283
- // Same page means same path and same query params
284
- (location.pathname === link.pathname && location.search === link.search)
285
- ) &&
286
- ev.button === 0 && // left clicks only
287
- !ev.metaKey && // new tab (mac)
288
- !ev.ctrlKey && // new tab (windows)
289
- !ev.altKey && // download
290
- !ev.shiftKey &&
291
- !ev.defaultPrevented &&
292
- transitionEnabledOnThisPage()
293
- ) {
294
- ev.preventDefault();
295
- navigate('forward', link.href, { index: ++currentHistoryIndex, scrollY: 0 });
296
- const newState: State = { index: currentHistoryIndex, scrollY };
297
- persistState({ index: currentHistoryIndex - 1, scrollY });
298
- history.pushState(newState, '', link.href);
277
+ !link ||
278
+ !(link instanceof HTMLAnchorElement) ||
279
+ !link.href ||
280
+ (link.target && link.target !== '_self') ||
281
+ link.origin !== location.origin ||
282
+ ev.button !== 0 || // left clicks only
283
+ ev.metaKey || // new tab (mac)
284
+ ev.ctrlKey || // new tab (windows)
285
+ ev.altKey || // download
286
+ ev.shiftKey || // new window
287
+ ev.defaultPrevented ||
288
+ !transitionEnabledOnThisPage()
289
+ )
290
+ // No page transitions in these cases,
291
+ // Let the browser standard action handle this
292
+ return;
293
+
294
+ // We do not need to handle same page links because there are no page transitions
295
+ // Same page means same path and same query params (but different hash)
296
+ if (location.pathname === link.pathname && location.search === link.search) {
297
+ if (link.hash) {
298
+ // The browser default action will handle navigations with hash fragments
299
+ return;
300
+ } else {
301
+ // Special case: self link without hash
302
+ // If handed to the browser it will reload the page
303
+ // But we want to handle it like any other same page navigation
304
+ // So we scroll to the top of the page but do not start page transitions
305
+ ev.preventDefault();
306
+ persistState({ ...history.state, scrollY });
307
+ scrollTo({ left: 0, top: 0, behavior: 'instant' });
308
+ if (location.hash) {
309
+ // last target was different
310
+ const newState: State = { index: ++currentHistoryIndex, scrollY: 0 };
311
+ history.pushState(newState, '', link.href);
312
+ }
313
+ return;
314
+ }
299
315
}
316
+
317
+ // these are the cases we will handle: same origin, different page
318
+ ev.preventDefault();
319
+ navigate('forward', link.href, { index: ++currentHistoryIndex, scrollY: 0 });
320
+ const newState: State = { index: currentHistoryIndex, scrollY };
321
+ persistState({ index: currentHistoryIndex - 1, scrollY });
322
+ history.pushState(newState, '', link.href);
300
323
});
324
+
301
325
addEventListener('popstate', (ev) => {
302
326
if (!transitionEnabledOnThisPage()) {
303
327
// The current page doesn't haven't View Transitions,
0 commit comments