Skip to content

Commit dd0c18d

Browse files
Merge branch 'canary' into fix/dev-error-reloading
2 parents 35d65da + ae0dbe5 commit dd0c18d

File tree

4 files changed

+201
-2
lines changed

4 files changed

+201
-2
lines changed

packages/next/next-server/server/incremental-cache.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,11 @@ export class IncrementalCache {
194194

195195
// TODO: This option needs to cease to exist unless it stops mutating the
196196
// `next build` output's manifest.
197-
if (this.incrementalOptions.flushToDisk && !data.isNotFound) {
197+
if (
198+
this.incrementalOptions.flushToDisk &&
199+
!data.isNotFound &&
200+
!data.isRedirect
201+
) {
198202
try {
199203
const seedPath = this.getSeedPath(pathname, 'html')
200204
await promises.mkdir(path.dirname(seedPath), { recursive: true })
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { useRouter } from 'next/router'
2+
3+
export default function Post(props) {
4+
const router = useRouter()
5+
6+
if (typeof window === 'undefined') {
7+
if (router.query.post?.startsWith('redir')) {
8+
console.log(router)
9+
throw new Error('render should not occur for redirect')
10+
}
11+
}
12+
13+
if (typeof window !== 'undefined' && !window.initialHref) {
14+
window.initialHref = window.location.href
15+
}
16+
17+
if (router.isFallback) return <p>Loading...</p>
18+
19+
return (
20+
<>
21+
<p id="gsp">getStaticProps</p>
22+
<p id="props">{JSON.stringify(props)}</p>
23+
</>
24+
)
25+
}
26+
27+
export const getStaticProps = ({ params }) => {
28+
if (params.post.startsWith('redir')) {
29+
let destination = '/404'
30+
31+
if (params.post.includes('dest-external')) {
32+
destination = 'https://example.com'
33+
} else if (params.post.includes('dest-')) {
34+
destination = params.post.split('dest-').pop().replace(/_/g, '/')
35+
}
36+
37+
let permanent = undefined
38+
let statusCode = undefined
39+
40+
if (params.post.includes('statusCode-')) {
41+
permanent = parseInt(
42+
params.post.split('statusCode-').pop().split('-').shift(),
43+
10
44+
)
45+
}
46+
47+
if (params.post.includes('permanent')) {
48+
permanent = true
49+
} else if (!statusCode) {
50+
permanent = false
51+
}
52+
let revalidate
53+
54+
if (params.post.includes('revalidate-')) {
55+
revalidate = 1
56+
}
57+
console.log('redirecting', {
58+
destination,
59+
permanent,
60+
statusCode,
61+
revalidate,
62+
})
63+
64+
return {
65+
redirect: {
66+
destination,
67+
permanent,
68+
statusCode,
69+
},
70+
revalidate,
71+
}
72+
}
73+
74+
return {
75+
props: {
76+
params,
77+
},
78+
}
79+
}
80+
81+
export const getStaticPaths = () => {
82+
return {
83+
paths: ['first', 'second'].map((post) => ({ params: { post } })),
84+
fallback: 'blocking',
85+
}
86+
}

test/integration/gssp-redirect/pages/gsp-blog/[post].js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,25 @@ export const getStaticProps = ({ params }) => {
4949
} else if (!statusCode) {
5050
permanent = false
5151
}
52+
let revalidate
53+
54+
if (params.post.includes('revalidate-')) {
55+
revalidate = 1
56+
}
57+
console.log('redirecting', {
58+
destination,
59+
permanent,
60+
statusCode,
61+
revalidate,
62+
})
5263

5364
return {
5465
redirect: {
5566
destination,
5667
permanent,
5768
statusCode,
5869
},
70+
revalidate,
5971
}
6072
}
6173

test/integration/gssp-redirect/test/index.test.js

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,90 @@ const runTests = (isDev) => {
110110
expect(pathname).toBe('/gsp-blog/redirect-dest-_gsp-blog_first')
111111
})
112112

113+
it('should apply redirect when fallback blocking GSP page is visited directly (internal dynamic)', async () => {
114+
const browser = await webdriver(
115+
appPort,
116+
'/gsp-blog-blocking/redirect-dest-_gsp-blog_first',
117+
true,
118+
true
119+
)
120+
121+
await browser.waitForElementByCss('#gsp')
122+
123+
const props = JSON.parse(await browser.elementByCss('#props').text())
124+
expect(props).toEqual({
125+
params: {
126+
post: 'first',
127+
},
128+
})
129+
const initialHref = await browser.eval(() => window.initialHref)
130+
const { pathname } = url.parse(initialHref)
131+
expect(pathname).toBe('/gsp-blog/first')
132+
})
133+
134+
it('should apply redirect when fallback blocking GSP page is visited directly (internal dynamic) second visit', async () => {
135+
const browser = await webdriver(
136+
appPort,
137+
'/gsp-blog-blocking/redirect-dest-_gsp-blog_first',
138+
true,
139+
true
140+
)
141+
142+
await browser.waitForElementByCss('#gsp')
143+
144+
const props = JSON.parse(await browser.elementByCss('#props').text())
145+
expect(props).toEqual({
146+
params: {
147+
post: 'first',
148+
},
149+
})
150+
const initialHref = await browser.eval(() => window.initialHref)
151+
const { pathname } = url.parse(initialHref)
152+
expect(pathname).toBe('/gsp-blog/first')
153+
})
154+
155+
it('should apply redirect when fallback blocking GSP page is visited directly (internal dynamic) with revalidate', async () => {
156+
const browser = await webdriver(
157+
appPort,
158+
'/gsp-blog-blocking/redirect-revalidate-dest-_gsp-blog_first',
159+
true,
160+
true
161+
)
162+
163+
await browser.waitForElementByCss('#gsp')
164+
165+
const props = JSON.parse(await browser.elementByCss('#props').text())
166+
expect(props).toEqual({
167+
params: {
168+
post: 'first',
169+
},
170+
})
171+
const initialHref = await browser.eval(() => window.initialHref)
172+
const { pathname } = url.parse(initialHref)
173+
expect(pathname).toBe('/gsp-blog/first')
174+
})
175+
176+
it('should apply redirect when fallback blocking GSP page is visited directly (internal dynamic) with revalidate second visit', async () => {
177+
const browser = await webdriver(
178+
appPort,
179+
'/gsp-blog-blocking/redirect-revalidate-dest-_gsp-blog_first',
180+
true,
181+
true
182+
)
183+
184+
await browser.waitForElementByCss('#gsp')
185+
186+
const props = JSON.parse(await browser.elementByCss('#props').text())
187+
expect(props).toEqual({
188+
params: {
189+
post: 'first',
190+
},
191+
})
192+
const initialHref = await browser.eval(() => window.initialHref)
193+
const { pathname } = url.parse(initialHref)
194+
expect(pathname).toBe('/gsp-blog/first')
195+
})
196+
113197
if (!isDev) {
114198
it('should apply redirect when fallback GSP page is visited directly (internal dynamic) 2nd visit', async () => {
115199
const browser = await webdriver(
@@ -435,15 +519,28 @@ describe('GS(S)P Redirect Support', () => {
435519
})
436520

437521
describe('production mode', () => {
522+
let output = ''
523+
438524
beforeAll(async () => {
439525
await fs.remove(join(appDir, '.next'))
440526
await nextBuild(appDir)
441527
appPort = await findPort()
442-
app = await nextStart(appDir, appPort)
528+
app = await nextStart(appDir, appPort, {
529+
onStdout(msg) {
530+
output += msg
531+
},
532+
onStderr(msg) {
533+
output += msg
534+
},
535+
})
443536
})
444537
afterAll(() => killApp(app))
445538

446539
runTests()
540+
541+
it('should not have errors in output', async () => {
542+
expect(output).not.toContain('Failed to update prerender files')
543+
})
447544
})
448545

449546
describe('serverless mode', () => {

0 commit comments

Comments
 (0)