next.js: [NEXT-428] AppDir: Static Page generation and build process fails for Dynamic Routes with Fetch (in Version >= 13.1.2)
Verify canary release
- I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
Platform: linux
Arch: x64
Version: #45~20.04.1-Ubuntu SMP Mon Apr 4 09:38:31 UTC 2022
Binaries:
Node: 16.15.1
npm: 8.11.0
Yarn: 1.22.19
pnpm: N/A
Relevant packages:
next: 13.1.3-canary.4
eslint-config-next: N/A
react: 18.2.0
react-dom: 18.2.0
Which area(s) of Next.js are affected? (leave empty if unsure)
App directory (appDir: true), Data fetching (gS(S)P, getInitialProps)
Link to the code that reproduces this issue
https://codesandbox.io/s/build-with-dynamic-routes-fails-in-next-13-1-2-ei0ms2
To Reproduce
Open a new terminal in the sandbox and runnpm run build
Describe the Bug
To generate the static pages, next fetches with [dynamic] as the query param. So instead of https://swapi.dev/api/people/1/?format=json
it fetches https://swapi.dev/api/people/[dynamic]/?format=json
.
In my production environment, that query can’t be handled by the API, no json is returned, or the JSON doesn’t match the promise (as you would expect), leading the build process to fails. The api in the code sandbox should return {"detail":"Not found"}
for the incorrect call, but it also says: Error: Failed to fetch data
.
This worked as intended in 13.1.1 and below.
Even if you catch these errors and the build process is successful, that should leave you with a static page without your desired data.
This will leave you with the following trace:
> build
> next build
warn - You have enabled experimental feature (appDir) in next.config.js.
warn - Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk.
info - Thank you for testing `appDir` please leave your feedback at https://nextjs.link/app-feedback
info - Creating an optimized production build
info - Compiled successfully
info - Linting and checking validity of types
info - Collecting page data
[= ] info - Generating static pages (0/4)https://swapi.dev/api/people/%5Bdynamic%5D/?format=json
[== ] info - Generating static pages (3/4)Error: Failed to fetch data
at getData (/sandbox/.next/server/app/[dynamic]/page.js:146:15)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Page (/sandbox/.next/server/app/[dynamic]/page.js:151:18)
[Error: An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this errorinstance which may provide additional details about the nature of the error.] {
digest: '2682591503'
}
Error occurred prerendering page "/[dynamic]". Read more: https://nextjs.org/docs/messages/prerender-error
Error: Failed to fetch data
at getData (/sandbox/.next/server/app/[dynamic]/page.js:146:15)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Page (/sandbox/.next/server/app/[dynamic]/page.js:151:18)
info - Generating static pages (4/4)
> Build error occurred
Error: Export encountered errors on following paths:
/[dynamic]/page: /[dynamic]
at /sandbox/node_modules/next/dist/export/index.js:409:19
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Span.traceAsyncFn (/sandbox/node_modules/next/dist/trace/trace.js:79:20)
at async /sandbox/node_modules/next/dist/build/index.js:1398:21
at async Span.traceAsyncFn (/sandbox/node_modules/next/dist/trace/trace.js:79:20)
at async /sandbox/node_modules/next/dist/build/index.js:1258:17
at async Span.traceAsyncFn (/sandbox/node_modules/next/dist/trace/trace.js:79:20)
at async Object.build [as default] (/sandbox/node_modules/next/dist/build/index.js:66:29)
Expected Behavior
According to the docs, dynamic routes will cause Next.js to render the whole route dynamically, at request time. Not sure if next just always tries to generatestatic pages as well, but this should not make the build process fail.
Which browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 7
- Comments: 19 (10 by maintainers)
Imo, having to use
export const dynamic = 'force-dynamic';
feels like an unnecessary step to me. If the route path contains ‘[]’ it is clearly a dynamic route and should be considered as such by default. Again, this was working in 13.1.1.If we need to have this for some other reason, may be it would be worth mentioning it in https://beta.nextjs.org/docs/routing/defining-routes#dynamic-segments
I could definitely give it a try, but it’s going to be faster trying and find the right person-whose-nick-starts-with-JJ-or-maybe-just-J 🤣
@lukasnevosad my guess is that somewhere in your page component, you’re throwing an uncaught error for the invalid
linkId
.From the error message, it looks like somewhere you’re validating the
linkId
and if it’s not valid, throwingnew Error('Invalid linkId "%5BlinkId%5D");'. Try wrapping the contents of your function /
render()method in
try { … } catch(e) { …}and return
notFound()(which you can import from
next/navigation`) instead of letting the error leave your component uncaught. My guess is that will solve your problem.If you don’t want to leverage the static page generation for that route and you’re not using
generateStaticParams
anyway, you can also addexport const dynamic = 'force-dynamic';
but I think handling the error is good practice anyway.Specifically, if you manually hit
/l/[linkId]
, I suspect you’re getting anHTTP 500
error which is a little blunt. Handling the error and returningnotFound()
would return anHTTP 404
which I feel is a little more appropriate.TL;DR:
export const dynamic = 'force-dynamic';
to dynamic routes withoutgenerateStaticParams
{ slug: '[slug]' }
)I ran into this issue. Specifically, it began to happen between v13.1.1 and v13.1.2.
The error in the console was a little convoluted, but the pertinent line is this:
Error occurred prerendering page "/blog/[slug]". Read more: https://nextjs.org/docs/messages/prerender-error
Between the aforementioned versions, the number of static pages that
next build
was trying to generated increased by 4 - also the same number of routes I have with dynamic components (e.g.[slug]
).The root cause appears to be that starting with v13.1.2, the build process attempts to generate pages for those routes where it hadn’t done before. Since
generateStaticParams
isn’t defined, it sends through dummy data equal to the parameter name,[slug]
in my case. My page component (defined in/app/blog/[slug]/page.tsx
) wasn’t gracefully handling the dummy value and was throwing an uncaught error.The suggested fix of adding
export const dynamic = 'force-dynamic';
to that file did not work in v13.1.2, however it did in v13.1.3. It seems that the fix does begin working in v13.1.3-canary.5, so I suspect #45015 was the solution.Since it only happened on that one route and not my other dynamic routes (which also don’t have
generateStaticParams
orexport const dynamic = 'force-dynamic';
specified), the underlying issue was my uncaught error (accessing a property on undefined).That said, even in the latest non-canary version (v13.1.5), I still get the same issue without
export const dynamic = 'force-dynamic';
. Perhaps there’s an opportunity to clarify in the documentation what is causing this error (and the potential fix)?