#Why is my page getting partially pre-rendered instead of being fully static

1 messages · Page 1 of 1 (latest)

meager pierBOT
#

Hi @buoyant birch. 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 knowledge sources provided, there are several reasons why your page might be getting partially pre-rendered (Partial Prerendering, or PPR) instead of being fully static, even if you are using Next.js 16 with cacheComponents: true.

1. Partial Prerendering (PPR) Is Explicitly Enabled

If you have set experimental_ppr = true in your layout.tsx or page.tsx, or enabled PPR in your next.config.js, your route will use Partial Prerendering. This means the static shell is pre-rendered, but any dynamic content (e.g., components using request-time data) will be streamed in as "holes" at runtime. This is the intended behavior of PPR and will override full static rendering for that route segment and its children unless you explicitly opt out by setting experimental_ppr = false in a child segment Partial Prerendering: Enabling PPR.

2. Use of Dynamic APIs or Data Fetching

If any component in your page or layout uses a dynamic API (such as cookies, headers, searchParams, or fetch with { cache: 'no-store' }), Next.js will treat that component as dynamic. In the context of PPR, this means the static shell is rendered at build time, but the dynamic part is deferred and streamed at request time How does Partial Prerendering work?.

3. Suspense Boundaries

If you wrap any component in a <Suspense> boundary and that component is dynamic, Next.js will treat the content inside Suspense as a dynamic "hole" to be streamed, while the rest of the page is statically rendered Partial Prerendering: Suspense.

#

4. Route Segment Config: dynamic Option

If you have not explicitly set export const dynamic = 'force-static' or export const dynamic = 'error' in your route segment config, Next.js will default to 'auto', which allows for partial prerendering if dynamic APIs are detected. To force full static rendering, you must set one of these options Route Segment Config Options.


What you should check:

  • Ensure you have not set experimental_ppr = true in your layout or page if you want full static rendering.
  • Make sure no components (including deeply nested ones) use dynamic APIs or fetch data with no-store.
  • Remove Suspense boundaries around dynamic components if you want the entire page to be static.
  • Explicitly set export const dynamic = 'force-static' or export const dynamic = 'error' in your layout.tsx and page.tsx to enforce static rendering.

If you share your layout.tsx and page.tsx, I can help you identify the specific cause in your code.

The knowledge sources do not mention a cacheComponents option in Next.js 16, so I cannot confirm its effect. Please ensure you are using the correct configuration options for your Next.js version.

For more details, see the official documentation on Partial Prerendering and Route Segment Config.

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

#

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

buoyant birch
#

I already gave you my layout.tsx and page.tsx @meager pier this is the themeProvider

"use cache";

import styles from "@/styles/home/page.module.css";

export default async function Home() {
    return (
        <div id={styles.page}>
            <main>
                {/* <LeftSide />
                <RightSide /> */}
            </main>
            <div className={styles.middle}>
                {/* <Curve /> */}
                <h2 className={styles.subTitle}>
                    The right balance of security and flexibility.
                </h2>
                <div className={styles.code}>
                    {/* <ServerCode />
                    <ClientCode /> */}
                </div>
                <h2 className={styles.subTitle}>
                    Easily manage your servers all in one place.
                </h2>
                {/* <Image alt="Dashboard" src="/dashboard.png" width={1082} height={484} />
                <Image
                    alt="Dashboard"
                    src="/dashboard-dark.png"
                    width={1082}
                    height={484}
                />
                <Curve /> */}
            </div>
            <h2 className={styles.subTitle}>
                Worry about your <span>apps</span>, <br /> not your pricing.
            </h2>
            {/* <div className={styles["pricing-cards"]}>
                {subscriptionPlansArray.map((plan) => (
                    <PricingCard
                        hoverEffect={false}
                        styles={styles}
                        key={plan.title}
                        {...plan}
                    >
                        <Link href="/signup">Get started now</Link>
                    </PricingCard>
                ))}
            </div> */}
        </div>
    );
}
meager pierBOT
#

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

#

Thank you for providing your Home component. Based on your code and the knowledge sources, here’s what I can determine:

Why Your Page Is Not Fully Static

Your Home component uses the "use cache" directive at the top, which should cache the entire route and make it eligible for static rendering, as long as there are no dynamic APIs or dynamic data fetching in the component or its children (use cache examples).

From the code you provided, all dynamic components and images are commented out, and there are no visible dynamic APIs (like cookies, headers, searchParams, or fetch with no-store). This means, in isolation, this component should be fully static and cached.

Possible Reasons for Partial Prerendering

  1. PPR or Dynamic Config in Parent Layout/Page
    If your layout.tsx or page.tsx (or any parent segment) has export const experimental_ppr = true, or if your next.config.js enables PPR globally, the route will use Partial Prerendering, even if the page itself is static (PPR config).

  2. Dynamic APIs in Other Components
    If any imported or nested component (even if currently commented out) uses a dynamic API, the route will be treated as partially dynamic. This includes any use of cookies, headers, searchParams, or uncached fetches (How PPR works).

#
  1. Route Segment Config Not Forcing Static
    If you want to guarantee full static rendering, you should set:

    export const dynamic = 'force-static'
    

    or

    export const dynamic = 'error'
    

    at the top of your page.tsx and/or layout.tsx (Route segment config).

  2. Global or Parent PPR/Cache Settings
    If cacheComponents or PPR is enabled globally or in a parent segment, it can affect the behavior of your route. The knowledge sources do not provide full details on the cacheComponents flag in Next.js 16, so I cannot confirm its exact effect.

What To Do

  • Check for experimental_ppr = true in your route or parent segments and remove it if you want full static rendering.
  • Add export const dynamic = 'force-static' to your page.tsx and layout.tsx to enforce static rendering.
  • Ensure no dynamic APIs are used in any imported or nested components, even if currently commented out.

If after these changes your page is still not fully static, there may be a configuration or framework-level issue not covered in the current knowledge sources.


Summary:
Your Home component, as shown, should be fully static with "use cache", unless PPR is enabled or dynamic APIs are used elsewhere in the route. Double-check your route segment configs and parent settings to ensure nothing is opting the route into partial prerendering (use cache, PPR config).

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