All questions

Adding fetchContent turned my statically generated pages dynamic, is that expected?

Asked by marina_p on

Mmarina_p

We run a marketplace with heavy ISR usage, thousands of prerendered pages. I added fetchContent from @croct/plug-next/server to one product landing page and the build output flipped that route from static to dynamic.

Is this expected behavior or did I wire something wrong? And if it is expected, how do people handle this at scale? Losing ISR across the site is not an option for us, we lean on it hard for traffic spikes.

Was this helpful?

2 answers

GSGuilherme SAccepted answer

Expected, and by design. fetchContent reads the incoming request (cookies, headers) to resolve content for that specific visitor, and anything that reads the request opts an App Router route into dynamic rendering. There is no way to personalize per visitor and serve everyone the same cached HTML at the same time.

The way we handle it at scale:

  • Only call fetchContent on routes that actually need personalization. The rest of the site stays static and keeps full ISR benefits. Do not sprinkle it into shared layouts.
  • For pages that must stay static but want some personalization, use the client-side hooks (useContent in a 'use client' component). The tradeoff is that the personalized bit swaps in after load instead of arriving in the HTML.

Some teams try to keep ISR by picking variants in middleware and rewriting to prebuilt variant pages. It works, but every experiment multiplies the pages you prebuild, and two concurrent tests already means four permutations. It gets combinatorial fast.

Was this helpful?
Mmarina_p

Makes sense. We only have a handful of pages worth personalizing anyway, so keeping it scoped to those sounds manageable.

Ddevpatel_

Just to add a data point on the dynamic rendering fear: we made the same switch on our highest traffic landing pages and the latency hit was smaller than expected. The content resolution itself is fast (Croct quotes under 90ms end to end at P95 and that matches what we see), so the page is dynamic but not slow. For us that was a simpler tradeoff than maintaining a rewrite matrix per experiment.

Was this helpful?
Still have questions?