Skip to content

Commit

Permalink
App Router: fix relative query/hash handling in next/link
Browse files Browse the repository at this point in the history
  • Loading branch information
keyz committed May 9, 2023
1 parent 5451564 commit 195757f
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 2 deletions.
4 changes: 2 additions & 2 deletions packages/next/src/client/components/app-router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ function Router({
navigateType: 'push' | 'replace',
forceOptimisticNavigation: boolean
) => {
const url = new URL(addBasePath(href), location.origin)
const url = new URL(addBasePath(href), location.href)

return dispatch({
type: ACTION_NAVIGATE,
Expand Down Expand Up @@ -261,7 +261,7 @@ function Router({
if (isBot(window.navigator.userAgent)) {
return
}
const url = new URL(addBasePath(href), location.origin)
const url = new URL(addBasePath(href), location.href)
// External urls can't be prefetched in the same way.
if (isExternalURL(url)) {
return
Expand Down
3 changes: 3 additions & 0 deletions test/e2e/app-dir/navigation/app/hash/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ export default function HashPage() {
<Link href="/hash#hash-300" id="link-to-300">
To 300
</Link>
<Link href="#hash-500" id="link-to-500">
To 500 (hash only)
</Link>
<Link href="/hash#top" id="link-to-top">
To Top
</Link>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Link from 'next/link'

export default function Page() {
return (
<>
<h1 id="h1">
<Link href="#h1" id="link-to-h1-hash-only">
To #h1, hash only
</Link>
</h1>

<p>
<Link href="?foo=1&bar=2" id="link-to-dummy-query">
Query only
</Link>
</p>

<h2 id="h2">
<Link href="?here=ok#h2" id="link-to-h2-with-hash-and-query">
To #h2, with both relative hash and query
</Link>
</h2>
</>
)
}
41 changes: 41 additions & 0 deletions test/e2e/app-dir/navigation/navigation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,52 @@ createNextDescribe(
await checkLink(50, 730)
await checkLink(160, 2270)
await checkLink(300, 4230)
await checkLink(500, 7030) // this one is hash only (`href="#hash-500"`)
await checkLink('top', 0)
await checkLink('non-existent', 0)
})
})

describe('relative hashes and queries', () => {
const pathname = '/nested-relative-query-and-hash'

it('should work with a hash-only url', async () => {
const browser = await next.browser(pathname)
await browser.elementByCss('#link-to-h1-hash-only').click()

await check(() => browser.url(), next.url + pathname + '#h1')
})

it('should work with a query-only url', async () => {
const browser = await next.browser(pathname)
await browser.elementByCss('#link-to-dummy-query').click()

await check(() => browser.url(), next.url + pathname + '?foo=1&bar=2')
})

it('should work with both relative hashes and queries', async () => {
const browser = await next.browser(pathname)
await browser.elementByCss('#link-to-h2-with-hash-and-query').click()

await check(() => browser.url(), next.url + pathname + '?here=ok#h2')

// Only update hash
await browser.elementByCss('#link-to-h1-hash-only').click()
await check(() => browser.url(), next.url + pathname + '?here=ok#h1')

// Replace all with new query
await browser.elementByCss('#link-to-dummy-query').click()
await check(() => browser.url(), next.url + pathname + '?foo=1&bar=2')

// Add hash to existing query
await browser.elementByCss('#link-to-h1-hash-only').click()
await check(
() => browser.url(),
next.url + pathname + '?foo=1&bar=2#h1'
)
})
})

describe('not-found', () => {
it('should trigger not-found in a server component', async () => {
const browser = await next.browser('/not-found/servercomponent')
Expand Down

0 comments on commit 195757f

Please sign in to comment.