#Generate only specific static routes with app router

1 messages · Page 1 of 1 (latest)

ashen spade
#

Right now I have the following code:

export async function generateStaticParams() {
  return [{params: {cat: 'hello'}}, {params: {cat: 'hi'}}]
}

export default async function Page({
  params,
}: {params: Promise<{cat: string}>}) {
  const a = (await params).cat
  return <>{a}</>
}

My structure is as followed /app/[cat]/page.tsx

Now, if I type in a slug that's not either /hello or /hi then it still works. In the old version of nextjs this will be redirect to a 404 page, but now it doesn't catch this error. How can I make sure that in this scenario, only the route hi and hello exist?

stiff mirageBOT
#

Hi @ashen spade. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To ensure that only the specific routes "/hello" and "/hi" exist and all other routes redirect to a 404 page in the Next.js App Router, you need to make a few adjustments to your code. Here's how you can achieve this:

  1. First, modify your generateStaticParams function to return the correct format:
export async function generateStaticParams() {
  return [{ cat: 'hello' }, { cat: 'hi' }]
}
  1. Then, add the dynamicParams configuration to your page file:
export const dynamicParams = false

By setting dynamicParams to false, you're telling Next.js to only render the paths returned by generateStaticParams and return a 404 for any other paths Next.js Dynamic Routes (https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes#generating-static-params).

Your final page.tsx file should look like this:

export const dynamicParams = false

export async function generateStaticParams() {
  return [{ cat: 'hello' }, { cat: 'hi' }]
}

export default async function Page({
  params,
}: {params: {cat: string}}) {
  return <>{params.cat}</>
}

With these changes:

  • Only "/hello" and "/hi" routes will be generated statically.
  • Any other route (e.g., "/test") will result in a 404 page.

Note that in the latest versions of Next.js, params is no longer a Promise in the App Router, so you don't need to await it Next.js generateStaticParams (https://nextjs.org/docs/app/api-reference/functions/generate-static-params#parameters).

#

Remember that during development (next dev), this behavior might not be immediately apparent as Next.js handles routes differently in development mode. To test the 404 behavior, you should build and run your application in production mode (next build followed by next start) Next.js Caching (https://nextjs.org/docs/app/building-your-application/caching#generatestaticparams).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@ashen spade Kapa.ai is still learning and improving, please let me know how I did by reacting below.

ashen spade
#

How about nextjs14?

#

@stiff mirage how about nextjs14?

stiff mirageBOT
#

Let me check the knowledge base for you again. Give me one moment! :books:

#

Next.js 14 maintains the same behavior for generating static routes in the App Router as described in my previous answer. The approach I outlined is still valid and recommended for Next.js 14.

However, it's worth noting a few points specific to Next.js 14:

  1. Next.js 14 continues to support and improve the App Router, which was introduced in version 13 Next.js 14 Release (https://nextjs.org/blog/next-14).

  2. The dynamicParams and generateStaticParams functions work the same way in Next.js 14 as they did in version 13.

  3. Next.js 14 has removed the next export command in favor of using "output": "export" in your next.config.js file for static exports Next.js Static Exports (https://nextjs.org/docs/pages/building-your-application/deploying/static-exports#version-history). This change doesn't directly affect your specific use case, but it's good to be aware of if you're considering a fully static export.

  4. The App Router in Next.js 14 continues to support React Server Components and other features introduced in version 13, which can be beneficial for optimizing your application's performance.

If you're using Next.js 14, the code I provided in the previous answer should work as expected. Just ensure you're using the latest best practices and syntax supported by Next.js 14, which in this case, remain the same as what I previously described.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@ashen spade Kapa.ai is still learning and improving, please let me know how I did by reacting below.

ashen spade
#

@stiff mirage

export async function generateStaticParams() {
  return [{ cat: 'hello' }, { cat: 'hi' }]
}

seems to not be working with locale?

stiff mirageBOT
#

Let me check the knowledge base for you again. Give me one moment! :books:

#

It appears that using generateStaticParams with locales in Next.js 14 and above may indeed cause some issues. This is a known problem that has been reported by several users.

According to a GitHub issue NEXT-979 (https://github.com/vercel/next.js/issues/46622), there's a bug where the i18n configuration in next.config.js breaks the generateStaticParams functionality for dynamic segments when running a production build. The default locale seems to be stripped from the page path, causing the export path not to match the pattern.

Here's an example of the error you might encounter:

Error: The provided export path '/blog/test-1' doesn't match the '/[lang]/blog/[slug]/page' page.

This issue appears to persist in Next.js 14 and even in some canary releases of Next.js 15.

Unfortunately, the knowledge sources don't provide a definitive solution to this problem. However, there are a few potential workarounds you could try:

  1. Remove the i18n configuration from your next.config.js file, if possible. This may not be ideal if you need internationalization for other parts of your application.

  2. Try using export const dynamic = 'force-static' in your page component. This has helped some users, as mentioned in the GitHub issue comments (https://github.com/vercel/next.js/issues/46622).

  3. If you're using output: "export" in your next.config.js, you might need to adjust your generateStaticParams function to include the locale explicitly.

Here's an example of how you might modify your generateStaticParams function to include locales:

export async function generateStaticParams() {
  const locales = ['en', 'es']; // Add your locales here
  const categories = ['hello', 'hi'];
  
  return locales.flatMap(locale => 
    categories.map(cat => ({ lang: locale, cat }))
  );
}
#

Please note that this is a complex issue, and the exact solution may depend on your specific setup and Next.js version. If these workarounds don't solve your problem, you might need to wait for an official fix from the Next.js team or consider alternative routing strategies.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@ashen spade Kapa.ai is still learning and improving, please let me know how I did by reacting below.

ashen spade
#

@stiff mirage why do I keep getting the following error?
A required parameter (cat) was not provided as an array received string in generateStaticParams for /[locale]/[...cat]

stiff mirageBOT
#

Let me check the knowledge base for you again. Give me one moment! :books:

#

Based on the error message you're encountering, it seems that there's a mismatch between the route structure you've defined and the parameters you're returning in your generateStaticParams function. Let's break down the issue and provide a solution:

  1. Your route structure appears to be /[locale]/[...cat], which indicates:

    • [locale] is a dynamic segment for language/locale
    • [...cat] is a catch-all segment for categories
  2. The error suggests that the cat parameter should be provided as an array, but it's receiving a string instead.

To resolve this issue, you need to adjust your generateStaticParams function to return the correct structure. Here's how you can modify it:

export async function generateStaticParams() {
  const locales = ['en', 'es']; // Add your locales here
  const categories = ['hello', 'hi'];
  
  return locales.flatMap(locale => 
    categories.map(cat => ({ 
      locale, 
      cat: [cat] // Note: cat is now an array
    }))
  );
}

In this modified version:

  • locale is a string, matching the [locale] segment
  • cat is an array, matching the [...cat] catch-all segment

This structure aligns with what Next.js expects for a route like /[locale]/[...cat].

It's worth noting that this issue is not specifically related to Next.js 14 or locales, but rather to how catch-all routes are handled in the App Router. The Next.js documentation on generateStaticParams (https://nextjs.org/docs/app/api-reference/functions/generate-static-params#catch-all-segments) provides examples of how to handle catch-all segments correctly.

#

If you're still encountering issues after making this change, it might be helpful to review your entire route setup and ensure that all parts of your application (route structure, generateStaticParams, and any other related configurations) are consistent with each other.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@ashen spade Kapa.ai is still learning and improving, please let me know how I did by reacting below.

ashen spade
#

ok i did that but i just got 404 error instead

#

@stiff mirage ok i did that but i just got 404 error instead

stiff mirageBOT
#

Let me check the knowledge base for you again. Give me one moment! :books:

#

I apologize for the confusion. It seems that the solution I provided earlier didn't fully resolve your issue. Let's try to troubleshoot this further.

The 404 error you're encountering could be due to a few reasons:

  1. The dynamicParams setting might be affecting the route generation.
  2. There might be a mismatch between the generated paths and the actual route structure.
  3. The build process might not be correctly generating the static pages.

Let's try a different approach:

  1. First, make sure your file structure matches your route. For a route like /[locale]/[...cat], your file should be located at app/[locale]/[...cat]/page.tsx.

  2. Modify your generateStaticParams function as follows:

export async function generateStaticParams() {
  const locales = ['en', 'es']; // Add your locales here
  const categories = ['hello', 'hi'];
  
  return locales.flatMap(locale => 
    categories.map(cat => ({ 
      locale, 
      cat: [cat]
    }))
  );
}

// Remove this line if you have it
// export const dynamicParams = false;

export default async function Page({ params }: { params: { locale: string, cat: string[] } }) {
  return <div>Locale: {params.locale}, Category: {params.cat.join('/')}</div>;
}
  1. In your next.config.js, ensure you don't have any conflicting configurations. If you're using the i18n configuration, it might interfere with the App Router's handling of locales.

  2. After making these changes, try rebuilding and starting your application:

npm run build
npm run start
  1. Test your routes. For example, try accessing:
    • /en/hello
    • /es/hi

If you're still encountering 404 errors, it would be helpful to know:

  • The exact URLs you're trying to access
  • The content of your next.config.js file
  • Any error messages you see in the console when building or running the application
#

Unfortunately, without more specific information about your setup and the exact error messages, it's challenging to pinpoint the exact cause of the 404 errors. The knowledge sources don't provide enough information to troubleshoot this specific scenario further. If the problem persists, you might want to consider creating a minimal reproduction of the issue and sharing it on the Next.js GitHub repository (https://github.com/vercel/next.js/issues) for more targeted assistance from the Next.js team or community.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@ashen spade Kapa.ai is still learning and improving, please let me know how I did by reacting below.

ashen spade
#

@stiff mirage It doesn't work. The page.tsx file is under app/[locale]/(base)/[...cat]/page.tsx

stiff mirageBOT
#

Let me check the knowledge base for you again. Give me one moment! :books:

#

I apologize for the confusion. Your file structure is different from what we initially assumed, which explains why the previous solutions didn't work. Let's address this specific case with the file located at app/[locale]/(base)/[...cat]/page.tsx.

The (base) segment in your file path is a route group, which doesn't affect the URL structure but helps organize your files. Given this information, let's modify the approach:

  1. Update your generateStaticParams function in app/[locale]/(base)/[...cat]/page.tsx:
export async function generateStaticParams() {
  const locales = ['en', 'es']; // Add your locales here
  const categories = ['hello', 'hi'];
  
  return locales.flatMap(locale => 
    categories.map(cat => ({ 
      locale, 
      cat: [cat]
    }))
  );
}

export default async function Page({ params }: { params: { locale: string, cat: string[] } }) {
  return <div>Locale: {params.locale}, Category: {params.cat.join('/')}</div>;
}
  1. Make sure you have dynamicParams = false set to ensure only the generated paths are valid:
export const dynamicParams = false;
  1. If you're using i18n configuration in your next.config.js, it might conflict with the App Router's handling of locales. Consider removing or adjusting it if possible.

  2. After making these changes, rebuild and start your application:

npm run build
npm run start
  1. Test your routes. For example, try accessing:
    • /en/hello
    • /es/hi

If you're still encountering issues, it's possible that there's a conflict between the App Router's handling of internationalization and your current setup. The knowledge sources indicate that there are known issues with i18n configuration and generateStaticParams in Next.js 14 GitHub Issue (https://github.com/vercel/next.js/issues/46622).

#

A potential workaround, if the above doesn't work, is to handle the locale routing in your middleware instead of relying on the file-system based routing for locales. This approach might help bypass some of the known issues with generateStaticParams and internationalization.

If you continue to face problems, it would be helpful to create a minimal reproduction of your issue and share it on the Next.js GitHub repository (https://github.com/vercel/next.js/issues) for more targeted assistance, as this seems to be a complex issue that might require attention from the Next.js team.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@ashen spade Kapa.ai is still learning and improving, please let me know how I did by reacting below.

ashen spade
#

@stiff mirage Ok how about if I have it like app/[locale]/blog/[...cat]/page.tsx

stiff mirageBOT
#

Let me check the knowledge base for you again. Give me one moment! :books:

#

Based on your updated file structure of app/[locale]/blog/[...cat]/page.tsx, we can adjust the generateStaticParams function to match this route pattern. Here's how you can modify your code:

export async function generateStaticParams() {
  const locales = ['en', 'es']; // Add your locales here
  const categories = ['hello', 'hi'];
  
  return locales.flatMap(locale => 
    categories.map(cat => ({ 
      locale, 
      cat: [cat]
    }))
  );
}

export const dynamicParams = false;

export default async function Page({ params }: { params: { locale: string, cat: string[] } }) {
  return <div>Locale: {params.locale}, Blog Category: {params.cat.join('/')}</div>;
}

This setup should generate the following routes:

  • /en/blog/hello
  • /en/blog/hi
  • /es/blog/hello
  • /es/blog/hi

However, it's important to note that there are known issues with generateStaticParams and internationalization in Next.js 14, as reported in the GitHub Issue: i18n config breaks dynamic segments export with generateStaticParams (https://github.com/vercel/next.js/issues/46622).

If you encounter problems with this setup, you might need to consider alternative approaches, such as:

  1. Handling locale routing in middleware instead of using file-based routing for locales.
  2. Using getStaticPaths in the Pages Router, if that's an option for your project.
  3. Exploring the use of export const dynamic = 'force-static' as mentioned in some of the GitHub issue comments.

If you continue to face issues, it might be worth creating a minimal reproduction of your problem and sharing it on the Next.js GitHub repository for more targeted assistance from the Next.js team or community.