Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[middleware] Fix hydration for rewrites to dynamic pages #32534

Merged
merged 2 commits into from Dec 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 8 additions & 5 deletions packages/next/shared/lib/router/router.ts
Expand Up @@ -1134,11 +1134,14 @@ export default class Router implements BaseRouter {
resolvedAs = delLocale(delBasePath(resolvedAs), this.locale)

/**
* If the route update was triggered for client-side hydration then
* do not check the preflight request. Otherwise when rendering
* a page with refresh it might get into an infinite loop.
* If the route update was triggered for client-side hydration and
* the rendered route is not dynamic do not check the preflight
* request as it is not necessary.
*/
if ((options as any)._h !== 1) {
if (
(options as any)._h !== 1 ||
isDynamicRoute(removePathTrailingSlash(pathname))
) {
const effect = await this._preflightRequest({
as,
cache: process.env.NODE_ENV === 'production',
Expand All @@ -1158,7 +1161,7 @@ export default class Router implements BaseRouter {
} else if (effect.type === 'redirect' && effect.destination) {
window.location.href = effect.destination
return new Promise(() => {})
} else if (effect.type === 'refresh') {
} else if (effect.type === 'refresh' && as !== window.location.pathname) {
window.location.href = as
return new Promise(() => {})
}
Expand Down
@@ -0,0 +1,5 @@
const PartsPage = () => {
return <div className="title">Parts page</div>
}

export default PartsPage
Expand Up @@ -57,6 +57,10 @@ export async function middleware(request) {
return fetch(url)
}

if (url.pathname.endsWith('/dynamic-replace')) {
return NextResponse.rewrite('/_interface/dynamic-path')
}

return new Response(null, {
headers: {
'req-url-basepath': request.nextUrl.basePath,
Expand Down
11 changes: 11 additions & 0 deletions test/integration/middleware/core/test/index.test.js
Expand Up @@ -455,6 +455,17 @@ function interfaceTests(locale = '') {
)
expect(res.headers.get('x-dynamic-path')).toBe('true')
})

it(`${locale} renders correctly rewriting to a different dynamic path`, async () => {
const browser = await webdriver(
context.appPort,
'/interface/dynamic-replace'
)
const element = await browser.elementByCss('.title')
expect(await element.text()).toEqual('Parts page')
const logs = await browser.log()
expect(logs.every((log) => log.source === 'log')).toEqual(true)
})
}

function getCookieFromResponse(res, cookieName) {
Expand Down