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

Unexpected behavior when using output: 'export', generateStaticParams(), and export const dynamic #56253

Open
1 task done
Yukigamine opened this issue Sep 30, 2023 · 55 comments
Labels
Dynamic Routes Related to dynamic routes. Output Related to the the output configuration option.

Comments

@Yukigamine
Copy link

Yukigamine commented Sep 30, 2023

Link to the code that reproduces this issue

https://codesandbox.io/p/sandbox/sweet-morning-nl3spx

To Reproduce

  1. Set output: 'export' in next.config.js
  2. Use generateStaticParams() in a Dynamic Route
  3. set export const dynamicParams = false and/or export const dynamic = 'force-static'
  4. Run next dev and attempt to visit a page on the dynamic route

Current vs. Expected behavior

Expected behavior:

Ignore the Route Segment Config options and/or generate a warning about them not being compatible.

Actual behavior:

Everything works correctly as long as you don't use output: 'export' and dynamic/dynamicParams together.

When they are, the following error is sent:
Error: Page "/[[...slug]]/page" is missing exported function "generateStaticParams()", which is required with "output: export" config.
The page is obviously not missing the function as it's right there and works fine under different configurations. This error occurs with all three types of Dynamic Routes when the Route Segment Configs are present with output: export. (Note: I have only tested with dynamic and dynamicParams so far.

If you take either of those conditions out, everything works as expected:

  • Without the output: export option, it will properly serve 404s when visiting a route that isn't generated.
  • Without the route segment config
    • visiting a generated param results in a proper site render
    • visiting a non-generated param results in an error saying the route must be generated due to output: export
  • With or without the route segment config, next build will export a valid configuration by generating HTML pages for each output of generateStaticParams.

The errors only actually happen in next dev when both of the aforementioned conditions are present.

This scenario probably just warrants updated documentation and maybe extra sanity checks.

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

yarn next info
yarn next info
yarn run v1.22.19
$ /project/home/yukigamine/workspace/node_modules/.bin/next info

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP PREEMPT_DYNAMIC Sun Aug  6 20:05:33 UTC 2023
Binaries:
  Node: 16.17.0
  npm: 8.15.0
  Yarn: 1.22.19
  pnpm: 7.1.0
Relevant Packages:
  next: 13.5.4-canary.8
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.1.3
Next.js Config:
  output: export


Done in 1.62s.

Which area(s) are affected? (Select all that apply)

App Router, Routing (next/router, next/navigation, next/link), Static HTML Export (output: "export")

Additional context

During testing, I went back to 13.4.19 and did not receive the error about generateStaticParams() missing under the circumstances described in this big report. I have not yet had a chance to look into whether the error just didn't exist yet or simply wasn't being thrown in that version, but it did entirely ignore the Route Segment Config options.

EDIT: For those looking for a workaround--

Rather than downgrading, simply remove export const dynamicParams = false and/or export const dynamic = 'force-static' from your file. These lines don't actually do anything in output: 'export' and just cause next dev to get confused.

@Yukigamine Yukigamine added the bug Issue was opened via the bug report template. label Sep 30, 2023
@github-actions github-actions bot added the Linking and Navigating Related to Next.js linking (e.g., <Link>) and navigation. label Sep 30, 2023
@wdavidw
Copy link

wdavidw commented Oct 5, 2023

I confirm. Rolling back to 13.4.19 fixed it.

@Yukigamine
Copy link
Author

I confirm. Rolling back to 13.4.19 fixed it.

@wdavidw I ended up sticking on the latest version but remove the dynamic and dynamicParams options because they don't apply when you have output: export set.

If you have your generateStaticParams() function set up properly, everything works without those two options.

@iRevolutionDev
Copy link

iRevolutionDev commented Oct 6, 2023

Same problem on next 13.5.4

image
image

@justoverclockl
Copy link

same problem for me

image

@the-dev-syntax
Copy link

the-dev-syntax commented Oct 10, 2023

the app was working fine , even with build
but after adding output: 'export' in next.config.js ,

gives error Error: Page "/[[...slug]]/page" is missing exported function "generateStaticParams()", which is required with "output: export" config.

but after removing it now new error appear :

invalid next.config.js options detected:
⚠ The value at .experimental has an unexpected property, images, which is not in the list of allowed properties

while this is the 13.5.2

any suggestion on how to fix it

@niimurank
Copy link

For the Python environment, this issue seems to be related. #54393

@kyuumeitai
Copy link

For me, the @Yukigamine solution works, thank you so much!

@stavros-k
Copy link

I confirm. Rolling back to 13.4.19 fixed it.

@wdavidw I ended up sticking on the latest version but remove the dynamic and dynamicParams options because they don't apply when you have output: export set.

If you have your generateStaticParams() function set up properly, everything works without those two options.

Without dynamic = 'force-static' / dynamic = false, I don't get 404 when I visit a non-existing generated page (eg /non-existent).
But it actually shows a page and passes the param (non-existent)

(Works fine after building and served)

@geanruca
Copy link

geanruca commented Oct 20, 2023

Downgrading to next 13.4.19 fixed it, but I'm not getting loaded correctly my js and CSS files

EDITL I fixed it adding assetPrefix: './' in next.config.js

@Yukigamine
Copy link
Author

I confirm. Rolling back to 13.4.19 fixed it.

@wdavidw I ended up sticking on the latest version but remove the dynamic and dynamicParams options because they don't apply when you have output: export set.
If you have your generateStaticParams() function set up properly, everything works without those two options.

Without dynamic = 'force-static' / dynamic = false, I don't get 404 when I visit a non-existing generated page (eg /non-existent). But it actually shows a page and passes the param (non-existent)

(Works fine after building and served)

That was what initially confused me because next dev was handling the dynamic routes that wouldn't actually be there during a build/export. So I added dynamic = 'force-static' / dynamic = false thinking I needed those too and then ran into this issue. Those two config options aren't needed when you actually export, but I feel like they should be implied or automatically activated so that next dev shows the same behavior you'll see when the site is statically exported.

But at the very least, the documentation should probably be updated so this situation is avoided or is less confusing.

PSA to everyone who downgraded, you can run the latest version of Next.JS, you just need to take out the dynamic = 'force-static' / dynamic = false options when running output: 'export'.

@bllfoad
Copy link

bllfoad commented Nov 3, 2023

I confirm. Rolling back to 13.4.19 fixed it.

@wdavidw I ended up sticking on the latest version but remove the dynamic and dynamicParams options because they don't apply when you have output: export set.

If you have your generateStaticParams() function set up properly, everything works without those two options.

Can i Have more details how to do this ? I feel Like I missed up

@vasyan
Copy link

vasyan commented Nov 5, 2023

Same problem. Downgrade works for me.

@wdavidw
Copy link

wdavidw commented Nov 6, 2023

I confirm. Rolling back to 13.4.19 fixed it.

@wdavidw I ended up sticking on the latest version but remove the dynamic and dynamicParams options because they don't apply when you have output: export set.
If you have your generateStaticParams() function set up properly, everything works without those two options.

Can i Have more details how to do this ? I feel Like I missed up

@bllfoad Have a look at how I update the source code in "page.js" of the TDP Website.

@Yukigamine
Copy link
Author

For me, Since it is exported statically with output: 'export', I think using useSearchParams() would be an alternative instead of using path segments. e.g localhost:3000/reset-password?token=myToken.

Search parameters and dynamic paths usually each have different use cases, but in their overlap (ie. /foo/slug/ vs /foo?bar=slug) the main difference is whether you want to get a 404 when trying to go somewhere that doesn't exist which is why you are required to define the paths that do exist for output: 'export'.

@wdavidw I ended up sticking on the latest version but remove the dynamic and dynamicParams options because they don't apply when you have output: export set.
If you have your generateStaticParams() function set up properly, everything works without those two options.

Can i Have more details how to do this ? I feel Like I missed up

Take a look at @wdavidw's example. Simply omitting or commenting out the lines with export const dynamicParams and/or export const dynamic should allow your generateStaticParams() function to work again.

@stylehuan
Copy link

Same problem. Downgrade works for me.

@Den-St
Copy link

Den-St commented Nov 13, 2023

What should i do if i want to write code like this

export default function StudyMaterialItemPage({params}:{params:{id:string}}) {
console.log(params);
return <></>
}

folder structure: study-materials/[id]/page.tsx

in next.config.js: output: 'export'

but getting error: Error: Page "/(userPages)/study-materials/[id]/page" is missing exported function "generateStaticParams()", which is required with "output: export" config.

@SergiAuletMur
Copy link

What should i do if i want to write code like this

export default function StudyMaterialItemPage({params}:{params:{id:string}}) { console.log(params); return <></> }

folder structure: study-materials/[id]/page.tsx

in next.config.js: output: 'export'

but getting error: Error: Page "/(userPages)/study-materials/[id]/page" is missing exported function "generateStaticParams()", which is required with "output: export" config.

Best option right now is to downgrade next to 13.4.19.
Hope this bug is fixed soon in the newer versions

@Yukigamine
Copy link
Author

What should i do if i want to write code like this

export default function StudyMaterialItemPage({params}:{params:{id:string}}) { console.log(params); return <></> }

folder structure: study-materials/[id]/page.tsx

in next.config.js: output: 'export'

but getting error: Error: Page "/(userPages)/study-materials/[id]/page" is missing exported function "generateStaticParams()", which is required with "output: export" config.

The error is telling you exactly what is wrong.
You need to add a generateStaticParams() function if you're going to use dynamic routes and output: "export".

Best option right now is to downgrade next to 13.4.19.
Hope this bug is fixed soon in the newer versions

There is no need to downgrade. Simply omitting or commenting out the lines with export const dynamicParams and/or export const dynamic should allow your generateStaticParams() function to work again. I'd barely call this a bug. It's more of a documentation issue with unclear error messages.

@mrkarimoff
Copy link

h unclear error messages.

But, how will you have a 404 page when the user enters a route segment that hasn't been generated by generateStaticParams?
We need to be able to show a 404 page to the user and export const dynamicParams = false is supposed to handle this, but it's not working

@Yukigamine
Copy link
Author

But, how will you have a 404 page when the user enters a route segment that hasn't been generated by generateStaticParams? We need to be able to show a 404 page to the user and export const dynamicParams = false is supposed to handle this, but it's not working

Your webserver handles that part. When you actually run next build it will only generate pages that are specified in generateStaticParams. The rest don't exist, so the webserver will return 404 if an invalid path is visited once the website is deployed.

@mrkarimoff
Copy link

But, how will you have a 404 page when the user enters a route segment that hasn't been generated by generateStaticParams? We need to be able to show a 404 page to the user and export const dynamicParams = false is supposed to handle this, but it's not working

Your webserver handles that part. When you actually run next build it will only generate pages that are specified in generateStaticParams. The rest don't exist, so the webserver will return 404 if an invalid path is visited once the website is deployed.

Okay then,where/how can I catch these errors and manually redirect to a custom 404 page?

@Yukigamine
Copy link
Author

Okay then,where/how can I catch these errors and manually redirect to a custom 404 page?

If you make a custom not-found using the built-in Next.js features, it will generate a 404.html file upon export. Then it's up to you to configure the webserver to send them there.

@uguraktas
Copy link

Same problem. Downgrade works for me.

Which version did you switch to?

@jadsonlourenco
Copy link

jadsonlourenco commented Nov 28, 2023

Yes, same bug when using "export" (v.14.0.3), dynamic route don't work. My system is client side only, so, the "fetch" works after the user sign in, so, I can get the "slug" of the router and fetch the data.

Temp solution: downgrade to version 13.4.19

EDIT: I've upgraded to new version again because the "13.4.19" has bugs. So, the solution now is don't use the "dynamic routes", use the "searchParams"...

@xml
Copy link

xml commented Dec 10, 2023

I think I'm in same situation as @jadsonlourenco : I'm using export for a pure client-side application, and just trying to use dynamic segments which will fetch data that relies on the segment data.

Per @Yukigamine 's comment:

You need to add a generateStaticParams() function if you're going to use dynamic routes and output: "export".

OK, but the docs actually say:

The generateStaticParams function can be used in combination with dynamic route segments to statically generate routes at build time instead of on-demand at request time.

That's exactly what I do not want to do. I don't want to memoize the params, nor pre-compile routes with them at build-time, as these are data-driven params which change constantly. Docs for generateStaticParams() do not mention this use-case at all, nor use of output:"export".

So... what are we supposed to do differently to support dynamic params with output:"export"?? <He asks with gratitude and perspective, but also confusion.>

@Yukigamine
Copy link
Author

So... what are we supposed to do differently to support dynamic params with output:"export"??

I may be wrong, but I don't think you can. The idea of output: "export" is is you are generating an entirely static site; the web server is not supposed to be doing anything other than serving files. If you have routes that are constantly changing, you need to be deploying Next.js using its node server, not exporting a static site.

@zdenham
Copy link

zdenham commented Mar 4, 2024

In my case, this error was caused by my static parameters function not returning the proper type--typo in the object value.

https://nextjs.org/docs/app/api-reference/functions/generate-static-params#returns

@ViceStudio
Copy link

In my case, this error was caused by my static parameters function not returning the proper type--typo in the object value.

https://nextjs.org/docs/app/api-reference/functions/generate-static-params#returns

Thanks. You helped me.

I had same issue. It was working in dev/build with no export flag. But then failed with explort flag. I was returning a straight array, return ["1","2"] it needs to be in the format:
return [{ id: "1" }, { id: "2" }];
}

@ae-mhd
Copy link

ae-mhd commented Mar 6, 2024

can any one tell me why still have this issue in Nextjs 14 , this is my code for user page
`// pages/users/[id]/page.js

import axios from 'axios';

export async function generateStaticParams() {
const api = https://jsonplaceholder.typicode.com/users;
const { data } = await axios.get(api);

// Generate static paths based on fetched data
const paths = data.map((user) => ({
    params: { id: user.id.toString() },
}));

return paths;

}

const Page = async ({ params }) => {
const api = https://jsonplaceholder.typicode.com/users/${params.id};
const { data } = await axios.get(api);
return (
<>

User Details


Name: {data.name}


Email: {data.email}


</>
);
};

export default Page;

`

@zdenham
Copy link

zdenham commented Mar 6, 2024

can any one tell me why still have this issue in Nextjs 14 , this is my code for user page `// pages/users/[id]/page.js

import axios from 'axios';

export async function generateStaticParams() { const api = https://jsonplaceholder.typicode.com/users; const { data } = await axios.get(api);

// Generate static paths based on fetched data
const paths = data.map((user) => ({
    params: { id: user.id.toString() },
}));

return paths;

}

const Page = async ({ params }) => { const api = https://jsonplaceholder.typicode.com/users/${params.id}; const { data } = await axios.get(api); return ( <>

User Details

Name: {data.name}

Email: {data.email}

</>
);
};
export default Page;

`

You should return the params directly, not an object with a params keys

@naota70
Copy link

naota70 commented Mar 9, 2024

@karpolan
This is a correction to a previous post.
I previously wrote export const dynamicParams = false, which worked in build but gave an error on my local server during development.
Apparently, the fallback mode of the production server cannot be set to 'static' unless you set export const dynamicParams = true.
We also added export const dynamic = 'force-static' across the board for pages that use components with 'use client' enabled.
Now both next dev and next build worked fine in my environment.

@muonu
Copy link

muonu commented Mar 9, 2024

this guy has it working with latest next.js. unfortunately I couldn't point to exactly what I was doing different. one thing I noticed was readdirSync does not respect '@' alias of next.js and has to be relative to root. ("./src/data/posts/") . also adding export const dynamicParams = false; as suggested by some folks (and not by others) further tripped me, removing this made it work.

@tmitchel2
Copy link

It looks like 14 fails if generateStaticParams returns an empty array, in 13 this was accepted.

@Felipe-Tomazetti
Copy link

Felipe-Tomazetti commented Mar 14, 2024

What should i do if i want to write code like this
export default function StudyMaterialItemPage({params}:{params:{id:string}}) { console.log(params); return <></> }
folder structure: study-materials/[id]/page.tsx
in next.config.js: output: 'export'
but getting error: Error: Page "/(userPages)/study-materials/[id]/page" is missing exported function "generateStaticParams()", which is required with "output: export" config.

The error is telling you exactly what is wrong. You need to add a generateStaticParams() function if you're going to use dynamic routes and output: "export".

Best option right now is to downgrade next to 13.4.19.
Hope this bug is fixed soon in the newer versions

There is no need to downgrade. Simply omitting or commenting out the lines with export const dynamicParams and/or export const dynamic should allow your generateStaticParams() function to work again. I'd barely call this a bug. It's more of a documentation issue with unclear error messages.

I can do this if I am not using server side components, but what if my projetct must be all client side?

@smikitky
Copy link

smikitky commented Apr 25, 2024

For now, you may be able to work around this by conditionally changing the output option, for example:

const nextConfig = {
  // Export only when building in GitHub Actions
  output: process.env.GITHUB_ACTION ? 'export' : undefined,
};

Then next dev works just fine.

@dayan2222
Copy link

Why don't you can just simply remove or comment output: 'export',? I also face a similar issue in my NextJS 14.1.2 and fix it simply by removing the output.

@Yukigamine

@Yukigamine
Copy link
Author

Why don't you can just simply remove or comment output: 'export',? I also face a similar issue in my NextJS 14.1.2 and fix it simply by removing the output.

My app doesn't require a backend, and the host I currently use doesn't support one. So I render it as a static site using the output: 'export' option and deploy the build folder to production. I discovered this odd behavior when I was using dynamic routes to create three pages that had different data but otherwise identical designs. Using generateStaticParams works perfectly since I know exactly what will be in those routes and it causes the export option to just generate an extra HTML page for each. But the confusion came up when I thought I also needed to set dynamic/dynamicParams so people didn't try to go to routes that don't exist. Turns out, if the routes don't exist, HTML pages don't get generated, and the webserver just returns a 404.

If I eventually choose new hosting where NextJS will run as the webserver, then I'll remove output: 'export' and need to use the dynamic/dynamicParams settings. My hope was that this issue would raise awareness to anyone who got confused like I did and possible advocate for an update to the documentation / error messages to make it more clear that these settings are incompatible.

@sam-shervin
Copy link

sam-shervin commented Jul 1, 2024

What should i do if i want to write code like this

export default function StudyMaterialItemPage({params}:{params:{id:string}}) { console.log(params); return <></> }

folder structure: study-materials/[id]/page.tsx

in next.config.js: output: 'export'

but getting error: Error: Page "/(userPages)/study-materials/[id]/page" is missing exported function "generateStaticParams()", which is required with "output: export" config.

put this in your page.tsx:

export function generateStaticParams() {
return [{ id: '1' }, { id: '2' }, { id: '3' }]
}

this will generate routes as: /study-materials/1, /study-materials/2, /study-materials/3

now if you had understood,
//write an API call which gets all the study materials' ids to generate static paths
//return the response using map

return Data.map((data) => ({
id: data.id.toString(),
}));

@TomasSestak

This comment has been minimized.

@WendaoLee
Copy link

I suppose this is the problem of the next dev,as I can correctly run next build to generate correct static page(with correct page redirect or 404 redirect) to deploy under Next.js v14.2.5.

It's the develop runtime problem(might be a bug of HMR,but I'm not sure), not the problem of developer.

richardnguyen99 added a commit to richardnguyen99/www.richardhnguyen.com that referenced this issue Sep 22, 2024
@amartuvshin-bold
Copy link

amartuvshin-bold commented Oct 20, 2024

Code
import { redirect } from 'next/navigation'
export async function generateStaticParams() {
const pageNames = ['a', 'b', 'c', 'd', 'e', 'f']

return pageNames.map((pageName) => ({
pageName,
}))
}
interface PageProps {
params: {
pageName: string
}
}
export default async function ProductPage({ params }: PageProps) {
const { pageName } = params

const validPageNames = ['a', 'b', 'c', 'd', 'e', 'f']

if (!validPageNames.includes(pageName)) {
redirect('/')
}
return (


{pageName} Page

)
}

/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
pageExtensions: ['tsx', 'ts'],
output: 'export',
experimental: {
pprFallbacks: true,
},
}

export default nextConfig

``
Next.js "^14.2.15"
Folder structure is app/products/[pageName]/page.tsx

Error : Page "/products/[pageName]/page" is missing param "/products/1" in "generateStaticParams()", which is required with "output: export" config.

Issue : When I try to access a non-existent page, it doesn't redirect to the 'Not Found' page. Additionally, after building the project with Next.js, it's not possible to directly access certain pages. If anyone has experienced this issue or knows a solution, I would appreciate your help. Thank you!

@Yukigamine
Copy link
Author

When I try to access a non-existent page, it doesn't redirect to the 'Not Found' page. Additionally, after building the project with Next.js, it's not possible to directly access certain pages. If anyone has experienced this issue or knows a solution, I would appreciate your help. Thank you!

@amartuvshin-bold that's just the error you get instead of a 404 when you're in the dev environment. When you run next build and load the output into a web server, the web server will serve a 404 when you try to access a page that doesn't exist.

@FacuMasino
Copy link

For now, you may be able to work around this by conditionally changing the output option, for example:

const nextConfig = {
  // Export only when building in GitHub Actions
  output: process.env.GITHUB_ACTION ? 'export' : undefined,
};

Then next dev works just fine.

Thanks! That worked for me, I was using Github Codespaces :)

@karpolan
Copy link

karpolan commented Dec 25, 2024

@samcx samcx added Output Related to the the output configuration option. Dynamic Routes Related to dynamic routes. and removed bug Issue was opened via the bug report template. Linking and Navigating Related to Next.js linking (e.g., <Link>) and navigation. labels Jan 29, 2025
@olsonpm
Copy link

olsonpm commented Apr 3, 2025

Ran into this just now and I believe I have the same use-case. I'm confused because this feels like a bug to me or at least a missing feature - not missing documentation. i.e. next dev should return a 404, not try to dynamically render the route.

@dev-tarun-nw
Copy link

Ran into this just now and I believe I have the same use-case. I'm confused because this feels like a bug to me or at least a missing feature - not missing documentation. i.e. next dev should return a 404, not try to dynamically render the route.

Hey @olsonpm,
do you found any solution or workaround for this ?

i have the similar issue, where I need to render a page with path /attempts/recording/<attempt_id>.

I am using standard react-router-dom and react-router, I have followed the official next.js migration docs fro cra.

@Yukigamine
Copy link
Author

Ran into this just now and I believe I have the same use-case. I'm confused because this feels like a bug to me or at least a missing feature - not missing documentation. i.e. next dev should return a 404, not try to dynamically render the route.

Which combination of output: and export const dynamic are you using?

I think the reason nex dev is not returning a 404 is because they're trying to be more specific and tell you that the route is not in generateStaticParams() but I'm not sure...

@olsonpm
Copy link

olsonpm commented Apr 7, 2025

output: 'export'
and
export const dynamicParams = false

I'm now using a workaround similar to those mentioned above which works fine

output: process.env.IS_LOCAL_DEV === 'true' ? undefined : 'export'

but I feel next dev shouldn't be trying to dynamically render the page when it's explicitly configured not to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Dynamic Routes Related to dynamic routes. Output Related to the the output configuration option.
Projects
None yet
Development

No branches or pull requests