Skip to content

Commit

Permalink
Fix usage of router.refresh() with Draft Mode in App Router (#50941)
Browse files Browse the repository at this point in the history
After enabling Draft Mode, `router.refresh()` was incorrectly causing the page to crash and do a full page refresh.

This PR fixes this case.

Co-authored-by: Steven <229881+styfle@users.noreply.github.com>
  • Loading branch information
ijjk and styfle committed Jun 9, 2023
1 parent 994c61a commit cdd366f
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 21 deletions.
38 changes: 19 additions & 19 deletions packages/next/src/server/base-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1351,25 +1351,6 @@ export default abstract class Server<ServerOptions extends Options = Options> {
return null
}

if (isAppPath) {
res.setHeader('vary', RSC_VARY_HEADER)

if (isSSG && req.headers[RSC.toLowerCase()]) {
if (!this.minimalMode) {
isDataReq = true
}
// strip header so we generate HTML still
if (
!isEdgeRuntime(opts.runtime) ||
(this.serverOptions as any).webServerConfig
) {
for (const param of FLIGHT_PARAMETERS) {
delete req.headers[param.toString().toLowerCase()]
}
}
}
}

delete query.__nextDataReq

// normalize req.url for SSG paths as it is not exposed
Expand Down Expand Up @@ -1492,6 +1473,25 @@ export default abstract class Server<ServerOptions extends Options = Options> {
}
}

if (isAppPath) {
res.setHeader('vary', RSC_VARY_HEADER)

if (!isPreviewMode && isSSG && req.headers[RSC.toLowerCase()]) {
if (!this.minimalMode) {
isDataReq = true
}
// strip header so we generate HTML still
if (
!isEdgeRuntime(opts.runtime) ||
(this.serverOptions as any).webServerConfig
) {
for (const param of FLIGHT_PARAMETERS) {
delete req.headers[param.toString().toLowerCase()]
}
}
}
}

let isOnDemandRevalidate = false
let revalidateOnlyGenerated = false

Expand Down
5 changes: 3 additions & 2 deletions test/e2e/app-dir/draft-mode/app/enable-and-redirect/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { draftMode } from 'next/headers'
import { redirect } from 'next/navigation'

export function GET() {
export function GET(req: Request) {
draftMode().enable()
return redirect('/some-other-page')
const to = new URL(req.url).searchParams.get('to') ?? '/some-other-page'
return redirect(to)
}
15 changes: 15 additions & 0 deletions test/e2e/app-dir/draft-mode/app/generate/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react'
import { RouteRefresher } from '../../../components/RouterRefresh'

export default async function Page() {
return (
<main>
<h1>With generateStaticParams</h1>
<RouteRefresher />
</main>
)
}

export function generateStaticParams() {
return [{ id: 'foo' }]
}
14 changes: 14 additions & 0 deletions test/e2e/app-dir/draft-mode/components/RouterRefresh.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use client'

import { useRouter } from 'next/navigation'
import React from 'react'

export function RouteRefresher() {
const router = useRouter()

return (
<button id="refresh" onClick={() => router.refresh()}>
Refresh
</button>
)
}
19 changes: 19 additions & 0 deletions test/e2e/app-dir/draft-mode/draft-mode-node.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createNextDescribe } from 'e2e-utils'
import { waitFor } from 'next-test-utils'

createNextDescribe(
'app dir - draft mode',
Expand Down Expand Up @@ -84,5 +85,23 @@ createNextDescribe(
const res = await next.fetch('/state', opts)
expect(await res.text()).toBe('ENABLED')
})

it('should not perform full page navigation on router.refresh()', async () => {
const to = encodeURIComponent('/generate/foo')
const browser = await next.browser(`/enable-and-redirect?to=${to}`)
await browser.eval('window._test = 42')
await browser.elementById('refresh').click()

const start = Date.now()
while (Date.now() - start < 5000) {
const value = await browser.eval('window._test')
if (value !== 42) {
throw new Error('Detected a full page navigation')
}
await waitFor(200)
}

expect(await browser.eval('window._test')).toBe(42)
})
}
)

0 comments on commit cdd366f

Please sign in to comment.