diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 271e26e226b3d..8524e31c77750 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -1550,7 +1550,10 @@ export default abstract class Server { isNotFound = (renderOpts as any).isNotFound isRedirect = (renderOpts as any).isRedirect - if (isAppPath && isSSG && isrRevalidate === 0) { + // we don't throw static to dynamic errors in dev as isSSG + // is a best guess in dev since we don't have the prerender pass + // to know whether the path is actually static or not + if (isAppPath && isSSG && isrRevalidate === 0 && !this.renderOpts.dev) { const staticBailoutInfo: { stack?: string description?: string diff --git a/test/e2e/app-dir/app-static/app-static.test.ts b/test/e2e/app-dir/app-static/app-static.test.ts index 7bb2e55ad5986..54cf0f431867a 100644 --- a/test/e2e/app-dir/app-static/app-static.test.ts +++ b/test/e2e/app-dir/app-static/app-static.test.ts @@ -58,6 +58,7 @@ createNextDescribe( 'force-static/page.js', 'force-static/second.html', 'force-static/second.rsc', + 'gen-params-dynamic/[slug]/page.js', 'hooks/use-pathname/[slug]/page.js', 'hooks/use-pathname/slug.html', 'hooks/use-pathname/slug.rsc', @@ -772,6 +773,26 @@ createNextDescribe( } }) + it('should not error with generateStaticParams and dynamic data', async () => { + const res = await next.fetch('/gen-params-dynamic/one') + const html = await res.text() + expect(res.status).toBe(200) + expect(html).toContain('gen-params-dynamic/[slug]') + expect(html).toContain('one') + + const data = cheerio.load(html)('#data').text() + + for (let i = 0; i < 5; i++) { + const res2 = await next.fetch('/gen-params-dynamic/one') + expect(res2.status).toBe(200) + expect( + cheerio + .load(await res2.text())('#data') + .text() + ).not.toBe(data) + } + }) + it('should honor dynamic = "force-static" correctly', async () => { const res = await next.fetch('/force-static/first') expect(res.status).toBe(200) diff --git a/test/e2e/app-dir/app-static/app/gen-params-dynamic/[slug]/page.js b/test/e2e/app-dir/app-static/app/gen-params-dynamic/[slug]/page.js new file mode 100644 index 0000000000000..52a6c3e572e8d --- /dev/null +++ b/test/e2e/app-dir/app-static/app/gen-params-dynamic/[slug]/page.js @@ -0,0 +1,35 @@ +export async function generateStaticParams() { + return [{ slug: 'one' }] +} + +const fetchRetry = async (url, init) => { + for (let i = 0; i < 5; i++) { + try { + return await fetch(url, init) + } catch (err) { + if (i === 4) { + throw err + } + console.log(`Failed to fetch`, err, `retrying...`) + } + } +} + +export default async function page({ params }) { + const { slug } = params + const data = await fetchRetry( + 'https://next-data-api-endpoint.vercel.app/api/random', + { + method: 'POST', + body: JSON.stringify({ hello: 'world' }), + } + ).then((res) => res.text()) + + return ( + <> +

/gen-params-dynamic/[slug]

+

{slug}

+

{data}

+ + ) +}