All questions

Our Strapi blog uses ISR, can I personalize one section without going fully dynamic?

Asked by ravi on

Rravi

Strapi feeds a Next.js App Router blog, ISR with revalidate 300. Build serves ~1200 posts, TTFB is great and I want to keep it that way.

Marketing wants a personalized CTA band on posts. I read that fetching Croct content in a server component makes the route dynamic, which would throw away ISR for the whole article.

Is there a pattern that keeps the article body static and personalizes just the CTA band? What is the actual tradeoff, because going fully dynamic for one section is not it

Was this helpful?

2 answers

TMTobias MeierAccepted answer

Your reading is correct: fetchContent reads the request, so calling it in a server component opts the route into dynamic rendering. Do not call it on routes you want to keep static. There is a whole thread on that behavior: fetchContent forces dynamic rendering.

The underlying constraint is not Croct-specific. ISR serves the same HTML to everyone, so any request-level personalization forces either dynamic rendering or middleware rewrites.

The hybrid pattern for your case: keep the route static and render only the CTA band with the client hook.

'use client';
import {useContent} from '@croct/plug-react';
export function CtaBand() {    const content = useContent('post-cta', {        fallback: {title: 'Try it free', buttonLabel: 'Start now'},    });
    return <Cta {...content} />;}

The tradeoff you accept is that one section resolves on the client, so the fallback renders first and the personalized version swaps in. The article body, layout, and everything above the fold stay in the static HTML. For a below-the-fold CTA band that swap is usually invisible; for a hero it would not be, and then you would weigh dynamic rendering instead.

Was this helpful?
Rravi

Band is below the fold, so the swap is acceptable. Shipping the hybrid.

Kkatien

Small addition: set a sensible fallback in useContent that matches your Strapi default styling exactly. If the fallback and the personalized variant share dimensions, the swap causes zero layout shift, which keeps CLS clean even though the content resolves client side.

Was this helpful?
Still have questions?