From 90273a9440f129b201c6391085e5ef932ecf92f9 Mon Sep 17 00:00:00 2001 From: Kanta Date: Wed, 13 Jan 2021 12:31:37 +0900 Subject: [PATCH 1/5] fix hydration mismatch on href for url with anchor refs --- packages/next/next-server/lib/router/router.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/next/next-server/lib/router/router.ts b/packages/next/next-server/lib/router/router.ts index e59fada6cbb1110..44cc9486e395912 100644 --- a/packages/next/next-server/lib/router/router.ts +++ b/packages/next/next-server/lib/router/router.ts @@ -163,7 +163,8 @@ export function delBasePath(path: string): string { * Detects whether a given url is routable by the Next.js router (browser only). */ export function isLocalURL(url: string): boolean { - if (url.startsWith('/')) return true + // prevent a hydration mismatch on href for url with anchor refs + if (url.startsWith('/') || url.startsWith('#')) return true try { // absolute urls can be local if they are on the same origin const locationOrigin = getLocationOrigin() From fc98fdeb1c644bbc59bc1b47e7d2901e337e84ea Mon Sep 17 00:00:00 2001 From: Kanta Date: Thu, 14 Jan 2021 12:43:51 +0900 Subject: [PATCH 2/5] add test --- .../integration/link-with-hash/pages/index.js | 23 +++++++++ .../link-with-hash/test/index.test.js | 47 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 test/integration/link-with-hash/pages/index.js create mode 100644 test/integration/link-with-hash/test/index.test.js diff --git a/test/integration/link-with-hash/pages/index.js b/test/integration/link-with-hash/pages/index.js new file mode 100644 index 000000000000000..3aeba3bd5fab8ed --- /dev/null +++ b/test/integration/link-with-hash/pages/index.js @@ -0,0 +1,23 @@ +import React from 'react' +import Link from 'next/link' + +if (typeof window !== 'undefined') { + window.caughtErrors = [] + const origError = window.console.error + window.console.error = function (...args) { + window.caughtErrors.push(args) + origError(...args) + } +} + +const Home = () => { + return ( + <> + + Hash Link + + + ) +} + +export default Home diff --git a/test/integration/link-with-hash/test/index.test.js b/test/integration/link-with-hash/test/index.test.js new file mode 100644 index 000000000000000..c1f82db86aca862 --- /dev/null +++ b/test/integration/link-with-hash/test/index.test.js @@ -0,0 +1,47 @@ +/* eslint-env jest */ + +import { join } from 'path' +import webdriver from 'next-webdriver' +import { + findPort, + launchApp, + killApp, + nextStart, + nextBuild, +} from 'next-test-utils' + +jest.setTimeout(1000 * 60 * 5) +let app +let appPort +const appDir = join(__dirname, '..') + +const runTests = () => { + it('should not have hydration mis-match for hash link', async () => { + const browser = await webdriver(appPort, '/') + const caughtErrors = await browser.eval(`window.caughtErrors`) + expect(caughtErrors).toEqual([]) + }) +} + +describe('Link with hash href', () => { + describe('development', () => { + beforeAll(async () => { + appPort = await findPort() + app = await launchApp(appDir, appPort) + }) + afterAll(() => killApp(app)) + + runTests() + }) + + describe('production', () => { + beforeAll(async () => { + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) + + runTests() + }) +}) From f13e7df8ef2e9668023bd071e634925c9a17ecb9 Mon Sep 17 00:00:00 2001 From: Kanta Date: Fri, 15 Jan 2021 19:09:27 +0900 Subject: [PATCH 3/5] read browser logs from webdriver for test --- test/integration/link-with-hash/pages/index.js | 9 --------- test/integration/link-with-hash/test/index.test.js | 14 ++++++++++++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/test/integration/link-with-hash/pages/index.js b/test/integration/link-with-hash/pages/index.js index 3aeba3bd5fab8ed..f39a8ed7342d281 100644 --- a/test/integration/link-with-hash/pages/index.js +++ b/test/integration/link-with-hash/pages/index.js @@ -1,15 +1,6 @@ import React from 'react' import Link from 'next/link' -if (typeof window !== 'undefined') { - window.caughtErrors = [] - const origError = window.console.error - window.console.error = function (...args) { - window.caughtErrors.push(args) - origError(...args) - } -} - const Home = () => { return ( <> diff --git a/test/integration/link-with-hash/test/index.test.js b/test/integration/link-with-hash/test/index.test.js index c1f82db86aca862..81be8baa560991b 100644 --- a/test/integration/link-with-hash/test/index.test.js +++ b/test/integration/link-with-hash/test/index.test.js @@ -18,8 +18,18 @@ const appDir = join(__dirname, '..') const runTests = () => { it('should not have hydration mis-match for hash link', async () => { const browser = await webdriver(appPort, '/') - const caughtErrors = await browser.eval(`window.caughtErrors`) - expect(caughtErrors).toEqual([]) + const browserLogs = await browser.log('browser') + let found = false + browserLogs.forEach((log) => { + if ( + log.message.includes( + 'Warning: Prop `%s` did not match. Server: %s Client: %s' + ) + ) { + found = true + } + }) + expect(found).toEqual(false) }) } From 00c0906ff160ad9cf559f3c10e8710db8d0ad238 Mon Sep 17 00:00:00 2001 From: kaykdm <34934746+kaykdm@users.noreply.github.com> Date: Fri, 15 Jan 2021 19:13:17 +0900 Subject: [PATCH 4/5] Update test/integration/link-with-hash/test/index.test.js Co-authored-by: Tim Neutkens --- test/integration/link-with-hash/test/index.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/link-with-hash/test/index.test.js b/test/integration/link-with-hash/test/index.test.js index 81be8baa560991b..c492c382c683db9 100644 --- a/test/integration/link-with-hash/test/index.test.js +++ b/test/integration/link-with-hash/test/index.test.js @@ -23,7 +23,7 @@ const runTests = () => { browserLogs.forEach((log) => { if ( log.message.includes( - 'Warning: Prop `%s` did not match. Server: %s Client: %s' + 'Warning: Prop' ) ) { found = true From c2f27b863c1ae464dfef76907cc84c5c7df67682 Mon Sep 17 00:00:00 2001 From: Kanta Kodama Date: Fri, 15 Jan 2021 19:46:26 +0900 Subject: [PATCH 5/5] fix lint --- .github/ISSUE_TEMPLATE/1.bug_report.yml | 4 ++-- test/integration/link-with-hash/test/index.test.js | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/1.bug_report.yml b/.github/ISSUE_TEMPLATE/1.bug_report.yml index 7bc9dedbb4fd017..d6b3957f5a83b31 100644 --- a/.github/ISSUE_TEMPLATE/1.bug_report.yml +++ b/.github/ISSUE_TEMPLATE/1.bug_report.yml @@ -12,10 +12,10 @@ inputs: value: If you leave out sections there is a high likelihood it will be moved to the GitHub Discussions "Help" section. - type: description attributes: - value: "Please first verify if your issue exists in the Next.js canary release line: `npm install next@canary`." + value: 'Please first verify if your issue exists in the Next.js canary release line: `npm install next@canary`.' - type: description attributes: - value: "next@canary is the beta version of Next.js. It includes all features and fixes that are pending to land on the stable release line." + value: 'next@canary is the beta version of Next.js. It includes all features and fixes that are pending to land on the stable release line.' - type: input attributes: label: What version of Next.js are you using? diff --git a/test/integration/link-with-hash/test/index.test.js b/test/integration/link-with-hash/test/index.test.js index c492c382c683db9..365cade8ad9bbf0 100644 --- a/test/integration/link-with-hash/test/index.test.js +++ b/test/integration/link-with-hash/test/index.test.js @@ -21,11 +21,7 @@ const runTests = () => { const browserLogs = await browser.log('browser') let found = false browserLogs.forEach((log) => { - if ( - log.message.includes( - 'Warning: Prop' - ) - ) { + if (log.message.includes('Warning: Prop')) { found = true } })