#why would this page opt to dynamic rendering?

1 messages · Page 1 of 1 (latest)

fickle olive
#

import { fetchCollectionSingleItemByQuery } from "@/lib/payloadFetchers";

import { fetchCollectionSingleItemByQuery } from "@/lib/payloadFetchers";

export default async function YearPage({
  params,
}: {
  params: Promise<{ year: string }>;
}) {
  const { year } = await params;
  const pagesYear = await fetchCollectionSingleItemByQuery({
    collectionSlug: "years",
    itemQuery: { year: { equals: year } },
  });
  return (
    <div>
      <div>year is {year}</div>
      <div>{JSON.stringify(pagesYear)}</div>
    </div>
  );
}

the file is [year]/page.tsx

obsidian pondBOT
#

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

#

This page would opt for dynamic rendering due to several factors:

  1. Dynamic Route Parameter: The page is using a dynamic route segment **year], which is accessed through the params prop. According to the [Next.js documentation** (https://nextjs.org/docs/app/api-reference/file-conventions/page#props), the params prop is a promise that resolves to an object containing the dynamic route parameters. This is considered a Dynamic API (https://nextjs.org/docs/app/building-your-application/rendering/server-components#dynamic-apis).

  2. Async Component: The page component is defined as an async function, which is a characteristic of Server Components that perform asynchronous operations.

  3. Data Fetching: The page is fetching data based on the dynamic year parameter using the fetchCollectionSingleItemByQuery function. This data fetching is likely not cached by default, as it depends on the dynamic input.

According to the Next.js documentation on Server Components (https://nextjs.org/docs/app/building-your-application/rendering/server-components#dynamic-rendering):

"During rendering, if a Dynamic API or a fetch option of { cache: 'no-store' } is discovered, Next.js will switch to dynamically rendering the whole route."

The use of the dynamic params prop in this case triggers dynamic rendering for the entire route.

It's worth noting that if you want to prerender some of the year pages statically, you could use generateStaticParams to specify which years should be prerendered at build time. Any years not included would still be dynamically rendered at request time, as explained in the Next.js documentation on replacing fallback (https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration#replacing-fallback).

#

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

fickle olive
#

@obsidian pond

1: I don't see in the doc where it's meantioned that dynamic route segments accesed through a param propis a dynamic api.

2: yes it's an async component. why did you even mentioned that? do async components cause a component to opt into dynamic rendering?

3: the component is even dynamic without that part

The use of the dynamic params prop in this case triggers dynamic rendering for the entire route. <-- are you sure about that?

obsidian pondBOT
#

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

#

I apologize for the confusion in my previous response. You're right to question these points, and I'll address each of your concerns based on the provided knowledge sources:

  1. You are correct. I made a mistake in my previous response. The params prop itself is not listed as a Dynamic API in the documentation. The Dynamic APIs (https://nextjs.org/docs/app/building-your-application/rendering/server-components#dynamic-apis) specifically include cookies, headers, searchParams, and a few others, but not the params prop.

  2. You're right to question this. I shouldn't have mentioned the async component as a reason for dynamic rendering. Async components themselves do not cause a route to opt into dynamic rendering. This was an error on my part.

  3. You're correct that the component would be dynamic even without the data fetching part. The reason for this is actually the use of the params prop itself, but not because it's a "Dynamic API" (which I incorrectly stated earlier).

Regarding the statement about the params prop triggering dynamic rendering, I need to correct this:

The params prop itself doesn't trigger dynamic rendering. However, according to the Next.js documentation on Dynamic Routes (https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes), when using dynamic route segments (like [year] in your case), the behavior is controlled by the dynamicParams option:

"Control what happens when a dynamic segment is visited that was not generated with generateStaticParams."

By default, dynamicParams is set to true, which means:

"Dynamic segments not included in generateStaticParams are generated on demand."

This explains why your route would be dynamically rendered unless you explicitly set dynamicParams to false or use generateStaticParams to prerender specific years.

#

I apologize for the inaccuracies in my previous response. Thank you for pointing these out, as it allows me to provide more accurate information based on the actual Next.js documentation.

Next.js Documentation on Dynamic Routes (https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes)

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

#

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

fickle olive
#

@obsidian pond ok then. one last question. why is this component do an API call every visit? I thought the result would be cached after a single fetch?

obsidian pondBOT
#

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

#

To answer your question about why the component is making an API call on every visit instead of caching the result after a single fetch, we need to look at the data fetching behavior in Next.js 13 and later versions.

According to the Next.js documentation on Data Fetching (https://nextjs.org/docs/app/building-your-application/data-fetching/fetching#fetch), the default behavior of fetch in Next.js 13 and later has changed:

"Data returned from fetch is not automatically cached in the Data Cache. The default caching behavior of fetch (e.g., when the cache option is not specified) is equal to setting the cache option to no-store"

This means that unless you explicitly set caching options, your fetchCollectionSingleItemByQuery function (which likely uses fetch under the hood) will make a new API call on every request.

To cache the result, you would need to add caching options to your fetch call. For example:

const pagesYear = await fetchCollectionSingleItemByQuery({
  collectionSlug: "years",
  itemQuery: { year: { equals: year } },
  cache: 'force-cache' // or { next: { revalidate: 3600 } } for time-based revalidation
});

However, it's important to note that even with caching, the dynamic nature of the route (using [year]) means that the page will still be dynamically rendered unless you use generateStaticParams to prerender specific years.

Next.js Documentation on Data Fetching (https://nextjs.org/docs/app/building-your-application/data-fetching/fetching#fetch)

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