Open In App

Next.js Functions: generateStaticParams

Last Updated : 05 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

generateStaticParams” is a function name or identifier used as a placeholder in the context of NextJS development. It doesn’t represent a built-in or standard function in NextJS itself. Instead, it seems to be a hypothetical function name that could be used to illustrate the process of generating static parameters in a NextJS application.

generateStaticParams:

The generateStaticParams function allows for the static generation of routes during the build process, when used alongside dynamic route segments, rather than dynamically generating them upon request.”

export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())

return posts.map((post) => ({
slug: post.slug,
}))
}

// using the `params` returned by `generateStaticParams`
export default function Page({ params }) {
const { slug } = params
// ...
}

Parameters

  • When multiple dynamic segments in a route utilize generateStaticParams, the child generateStaticParams function is triggered for each set of parameters generated by the parent.
  • The params object holds the populated parameters from the parent generateStaticParams, enabling their utilization for generating parameters within a child segment.

Return Type

  • generateStaticParams needs to give back a list of items. Each item in the list should represent a dynamic part of the route that’s been filled with data.
  • In each item, there should be a part that represents the name of the dynamic segment, and another part that holds the actual value to fill in for that segment.

Single Dynamic Segment

export function generateStaticParams() {
return [{ id: 'a' }, { id: 'b' }, { id: 'c' }]
}

export default function Page({ params }: { params: { id: string } }) {
const { id } = params
}

In this example, the route is `app/student/[id]/page.tsx`, featuring a single dynamic segment `[id]`. The `generateStaticParams` function provides an array with three objects, each containing a different `id` value. Consequently, three versions of this page will be statically generated, accessible via the URLs `/student/1`, `/student/2`, and `/student/3`. Within the `Page` component, the `id` is obtained from the `params` object, facilitating its usage for further processing.

Multiple Dynamic Segments

export function generateStaticParams() {
return [
{ name: 'a', subject: 'english' },
{ name: 'b', subject: 'hindi' },
{ name: 'c', subject: 'maths' },
]
}


export default function Page({
params,
}: {
params: { category: string; product: string }
}) {
const { category, product } = params
// ...
}

In this scenario, the route is app/student/[name]/[subject]/page.tsx, comprising two dynamic segments [name] and [subject]. The generateStaticParams function returns an array of objects, each specifying various combinations of name and subject. As a result, three versions of this page will be statically generated, accessible via URLs like /student/a/english, /student/b/hindi, and /student/c/maths. Inside the Page component, the params object should contain properties for both name and subject, allowing us to extract and utilize these values for further processing.

Catch-all Dynamic Segment

export function generateStaticParams() {
return [{ slug: ['a', 'english'] }, { slug: ['b', 'hindi] }, { slug: ['c', 'maths'] }]
}


export default function Page({ params }: { params: { slug: string[] } }) {
const { slug } = params
// ...
}

In this example, the route is `app/student/[…slug]/page.tsx`, featuring a catch-all dynamic segment `[…slug]`, allowing for variable path lengths. The `generateStaticParams` function returns an array of objects, each containing an array within the `slug` property, representing different combinations of values. Consequently, multiple versions of this page will be statically generated, with URLs like `/student/a/english`, `/student/b/hindi`, and `/student/c/maths`. Inside the `Page` component, the `params` object includes an array `slug`, enabling us to access and utilize the variable path segments for further processing.

Generate params from the bottom up

export async function generateStaticParams() {
const products = await fetch('https://.../products').then((res) => res.json())

return products.map((product) => ({
category: product.category.slug,
product: product.id,
}))
}

export default function Page({
params,
}: {
params: { category: string; product: string }
}) {
// ...
}

Dynamic segments starting from the child route segment and moving towards the parent route segment.

For example, in the route app/products/[category]/[product]/page.tsx, we want to generate params for both [category] and [product]. To achieve this, we utilize the generateStaticParams function.

This function asynchronously fetches product data from an API and maps each product to an object containing category and product properties. These properties represent dynamic segments that will populate the route.

Inside the Page component, we receive category and product as parameters from the params object, enabling us to use them for rendering content related to specific product categories and products.

Generate params from the top down:


export async function generateStaticParams({
params: { category },
}: {
params: { category: string }
}) {
const products = await fetch(
`https://.../products?category=${category}`
).then((res) => res.json())

return products.map((product) => ({
product: product.id,
}))
}

export default function Page({
params,
}: {
params: { category: string; product: string }
}) {
// ...
}

Generating params from the top down means first creating the parent route segment and then using it to create the child route segment.

For example, let’s consider the route app/products/[category]/layout.tsx. Here, we want to generate parameters for the [category] segment. The generateStaticParams function fetches product data and creates an object for each product with its category.

In the Layout component, we receive the category as a parameter from the params object. This allows us to show content specific to product categories.

In the child route segment app/products/[category]/[product]/page.tsx, the generateStaticParams function runs for each category created by the parent. It fetches product data based on the category received from the parent.

As a result, the Page component gets both category and product parameters from the params object, helping us display content for specific products within their respective categories.

Generate only a subset of params

export const dynamicParams = false

export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
const topPosts = posts.slice(0, 10)

return topPosts.map((post) => ({
slug: post.slug,
}))
}

Generating only a subset of params for a route involves returning an array of objects with specific dynamic segments. By using the dynamicParams segment config option, you can manage what occurs when a dynamic segment is accessed that wasn’t generated with generateStaticParams.

For instance, in the route app/blog/[slug]/page.js, we limit the params to show only the top 10 posts. We set dynamicParams to false, indicating that any dynamic segment beyond the top 10 posts will result in a 404 error.

The generateStaticParams function fetches posts and selects the top 10. It then creates an array of objects, each containing the slug of a post. This array serves as the subset of params for the route.

As a result, only the top 10 posts will have dynamically generated pages, while accessing other posts will lead to a 404 error.

Purpose

  • Next.js allows you to generate pages statically at build time using data from external sources like APIs or databases.
  • Static generation helps improve performance by pre-rendering pages with data that doesn’t change frequently.

Static Paths

  • When a Next.js application is built, it needs to know what pages to generate statically.
  • The getStaticPaths function is used to define a list of paths that should be statically generated based on dynamic data.
  • Each path can include parameters, allowing for dynamic content generation.

Dynamic Routes

  • Next.js supports dynamic routes, where parts of the URL are treated as parameters.
  • For example, in /posts/[id], [id] is a parameter representing a dynamic value.
  • By generating static paths with parameters, Next.js can pre-render pages for all possible parameter values.

Data Fetching

  • Once the static paths are defined, Next.js needs to fetch data for each path to pre-render the pages.
  • The getStaticProps function is used to fetch data for a specific path based on its parameters.
  • This function runs at build time and receives the parameters of the current path as input.

Rendering Process

  • During the build process, Next.js first calls getStaticPaths to determine the list of paths to pre-render.
  • For each path, it then calls getStaticProps to fetch data and pre-render the page.
  • The pre-rendered pages are saved as static HTML files, which are served to users for improved performance.

What we are going to do

  • We’re going to build a Next.js application that implements dynamic routing for blog posts. Initially, we’ll fetch the blog post data dynamically from an external API (https://jsonplaceholder.typicode.com/posts). Each blog post will have a unique slug in the URL, such as /blog/[slug], where the slug represents the ID of the blog post. We’ll start by setting up dynamic routing to render the blog post content based on the slug parameter in the URL.
  • After successfully implementing dynamic routing, we’ll optimize our application by using static parameter generation. This involves pre-generating the pages for all possible blog post slugs during the build process, improving performance by serving pre-rendered pages instead of fetching data dynamically on each request.
  • To achieve this, we’ll use Next.js’s getStaticPaths and getStaticProps functions. We’ll modify our existing dynamic routing setup to use static parameter generation, ensuring that the blog post pages are pre-rendered at build time. This approach enhances the user experience by reducing loading times and server load, resulting in a faster and more responsive application.

Step 1: Initialize a NextJS Project:

npx create-next-app my-next-app

Step 2: Create the Blog Post Page

Inside the app directory, create a new directory named blog. and then create a new directory named [slug] inside the blog then create a file as page.js

Screenshot-2024-03-23-173438

project structure

Step 3: Fetch Blog Post Data Dynamically:

With this code, we’ve established dynamic routes for blog posts. When a user visits a page, the component fetches data from an external API to display the corresponding blog post. However, each time the page is loaded, it triggers a new API call, leading to redundant requests if the same URL is accessed repeatedly. Add this in page.js that you have created

JavaScript
export default async function BlogPost({ params }) {

    const { slug } = params;
    console.log(params.slug)
    const data1 = await fetch(
`https://jsonplaceholder.typicode.com/posts/${params.slug}`)
    const udata = await data1.json()

    return (
        <div>
            <h1>Blog Post</h1>
            <div>
                <h1>{udata.title}</h1>
                <div>{udata.body}</div>
            </div>
        </div>
    );
}

Step 4: Implementing getStaticPaths:

To address above issue, we’ll implement generateStaticParams in Next.js, a feature known as static parameter generation. This allows us to pre-generate all possible blog post pages during the build process, ensuring that each page is readily available without the need for additional API calls. By doing so, we optimize performance by serving pre-rendered pages, eliminating the need to hit the API every time a user accesses a blog post URL.

JavaScript
export async function generateStaticParams() {

  const product = await fetch('https://jsonplaceholder.typicode.com/posts');
  const posts = await  product.json();
  return posts.map((i)=>({
        slug : i.id.toString(),
    }))
 
}

export default async function  BlogPost({ params }  ) {

  const { slug } = params;
  console.log(params.slug)
  const data1 = await fetch(`
 https://jsonplaceholder.typicode.com/posts/${params.slug}`)
  const udata = await data1.json()
  
  
  return (
    <div>
      <h1>Blog Post</h1>
      <div>
        <h1>{udata.title}</h1>
        <div>{udata.body}</div>
      </div>
    </div>
  );
}

Step 5: Build the Project: Run the build command to generate the optimized production build of the Next.js project.

npm run build

By building the project, Next.js generates the generateStaticParams at build time, saving them in the .next folder. This means that the HTML files for each blog post page are pre-generated during the build process. As a result, when a user accesses a blog post page, the content is immediately available without the need for additional API calls. This optimization significantly reduces loading times and minimizes the number of API requests, enhancing the overall performance and user experience of the website.

Start the Development Server:

npm run dev

Output:

Recording-2024-03-23-184443

final output of the project




Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads