Skip to content

Commit 267487e

Browse files
authored
Prevent navigation on hash change (#7824)
1 parent b063a2d commit 267487e

File tree

4 files changed

+28
-2
lines changed

4 files changed

+28
-2
lines changed

.changeset/moody-beers-leave.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
Prevent navigation on hash change

packages/astro/components/ViewTransitions.astro

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ const { fallback = 'animate' } = Astro.props as Props;
148148
link.href &&
149149
(!link.target || link.target === '_self') &&
150150
link.origin === location.origin &&
151+
!link.hash &&
151152
ev.button === 0 && // left clicks only
152153
!ev.metaKey && // new tab (mac)
153154
!ev.ctrlKey && // new tab (windows)
@@ -162,13 +163,19 @@ const { fallback = 'animate' } = Astro.props as Props;
162163
history.pushState({ index: currentHistoryIndex }, '', link.href);
163164
}
164165
});
165-
window.addEventListener('popstate', () => {
166+
window.addEventListener('popstate', ev => {
166167
if (!transitionEnabledOnThisPage()) {
167168
// The current page doesn't haven't View Transitions,
168169
// respect that with a full page reload
169170
location.reload();
170171
return;
171172
}
173+
// hash change creates no state.
174+
if(ev.state === null) {
175+
history.replaceState({ index: currentHistoryIndex }, '');
176+
ev.preventDefault();
177+
return;
178+
}
172179
const nextIndex = history.state?.index ?? currentHistoryIndex + 1;
173180
const direction: Direction = nextIndex > currentHistoryIndex ? 'forward' : 'back';
174181
navigate(direction, location.href);

packages/astro/e2e/fixtures/view-transitions/src/pages/one.astro

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import Layout from '../components/Layout.astro';
33
---
44
<Layout>
55
<p id="one">Page 1</p>
6+
<a id="click-one" href="#test">test</a>
67
<a id="click-two" href="/two">go to 2</a>
78
<a id="click-three" href="/three">go to 3</a>
9+
10+
<div id="test">test content</div>
811
</Layout>

packages/astro/e2e/view-transitions.test.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,20 @@ test.describe('View Transitions', () => {
153153
});
154154

155155
test('astro:load event fires when navigating directly to a page', async ({ page, astro }) => {
156-
// Go to page 1
156+
// Go to page 2
157157
await page.goto(astro.resolveUrl('/two'));
158158
const article = page.locator('#twoarticle');
159159
await expect(article, 'should have script content').toHaveText('works');
160160
});
161+
162+
test('click hash links does not do navigation', async ({ page, astro }) => {
163+
// Go to page 1
164+
await page.goto(astro.resolveUrl('/one'));
165+
const p = page.locator('#one');
166+
await expect(p, 'should have content').toHaveText('Page 1');
167+
168+
// Clicking 1 stays put
169+
await page.click('#click-one');
170+
await expect(p, 'should have content').toHaveText('Page 1');
171+
});
161172
});

0 commit comments

Comments
 (0)