#Layout and page re-rendering in production mode for each load

1 messages · Page 1 of 1 (latest)

violet fiber
#

I have a NextJS version 14.2.5 app router setup with only one route [[...slug]] with this content at the top of page.tsx:

export const dynamic = 'force-static';
export const generateStaticParams = async () => [];
export const revalidate = 120;

The problem is that after I do yarn build and yarn start and then navigate to any route - my layout and page gets rendered twice even if I have no state or extra content with barebones setup. This is causing me issues because I want to set up some data fetching at the route level and it runs twice. Any ideas why this route and layout is being re-rendered for each visit? And how can I fix that?

wise furnaceBOT
#

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

#

Based on the information in the knowledge sources, the double rendering of your layout and page in production mode—even with a barebones setup and static configuration—is a known issue in certain scenarios with the Next.js App Router.

Why is this happening?

  • Double Rendering During Static Generation: Next.js, when generating static pages, sometimes "walks" (renders) the component tree twice: once to generate the HTML and once to generate the React Server Component (RSC) payload. This is necessary for static export so that client navigations have the required RSC data. This behavior can cause your data fetching logic to run twice during the build or on-demand revalidation, even if you have no state or extra content in your components. This is not limited to development mode; it also happens in production builds and static exports 2X rendering/2X fetch calls on page revalidation ISR [production build].

  • App Router and Layout Re-renders: There are also open issues where layouts and pages re-render more than expected, especially with certain routing setups (like catch-all routes or parallel routes). This can happen even if you use static generation and have no dynamic state. The root cause is often related to how Next.js handles routing context and fallback boundaries internally, which can trigger extra renders layout.tsx renders twice when using SSR and parallel routes, App router: Components in root layout rerender on navigation.

#
  • Not a Bug (in Some Cases): In some cases, this is considered expected behavior by the Next.js team, especially for static pages, due to the need to generate both HTML and RSC payloads. However, there are ongoing discussions and some fixes in recent versions to reduce unnecessary renders, but as of your version (14.2.5), this behavior may still be present.

What can you do?

  • Avoid Side Effects in the Component Body: If your data fetching is causing issues due to double rendering, ensure that any side effects (like logging, analytics, or non-idempotent fetches) are not placed directly in the component body. Use memoization or move such logic to a place where it won't be triggered by both renders.

  • Check for Updates: Some improvements have been made in recent canary releases to reduce double rendering during static generation. Consider testing with the latest canary version to see if your issue is resolved.

  • Understand Limitations: If you are using static generation with ISR (revalidate), some double rendering during build or revalidation is currently expected and may not be fully avoidable until further improvements are released by the Next.js team.

#

Summary:
The double rendering you observe is a known behavior in Next.js App Router, especially with static generation and ISR. It is due to the way Next.js generates both HTML and RSC payloads for static pages. There is no complete fix as of version 14.2.5, but you can mitigate issues by ensuring your data fetching is idempotent and side-effect free, and by keeping an eye on future Next.js releases for improvements 2X rendering/2X fetch calls on page revalidation ISR [production build], layout.tsx renders twice when using SSR and parallel routes.

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