#vercel not caching my page

1 messages · Page 1 of 1 (latest)

cyan fiber
#

Hey,

I have a SSR page which fetches some data from my database and displays it on my web page.

I have attempted to use revalidate = 240 to make the cache refresh every 240 seconds. However, after checking the response headers I am getting cache-control: private, no-cache, no-store, max-age=0, must-revalidate back from vercel. What have I done wrong? I am on version "next": "^15.0.1",

export const revalidate = 240;

export default async function Home() {
    const totalApplications = await db.applications.count();

    return (
        <HydrateClient>
            <div className="h-full">
                            <h1>{totalApplications}</h1>
            </div>
        </HydrateClient>
    );
}
dull pathBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)

snow flint
# cyan fiber Hey, I have a SSR page which fetches some data from my database and displays i...

when using revalidate the page will be cached inside the full route cache. That means, that it's cached on the server, shared with other users and can be revalidated.

And here is the key point: it's cache on the server. What you seeing there "cache-control: private, no-cache..." are the instructions for the browser. But we don't use the browser cache here. We using the full route cache here

cyan fiber
#

oh wait, i think this icon "edge cache" means it is being cached! thank you for the response b33 🙂

#

damn! there is one problem though, if im caching this route it doesn't fetch the users session on each render, that is a slight problem. Surely there is a way to only cache the server sided logic?

#

so im using export const revalidate = 240; in my page.tsx and then I have a layout.tsx in the same directory (public)

export default function Layout({ children }: { children: React.ReactNode }) {
    return (
        <main className="flex min-h-screen flex-col xl:p-0">
            <PublicNavBar />
            {children}
            <PublicFooter />
        </main>
    );
}

And inside of <PublicNavBar> I fetch the session nextauth session await auth().

#

I do not have any cache defined for "Layout", but im guessing because of the cache i defined for the page it uses that instead? which isn't ideal.

#

it appears that I could potentially move my fetching session logic onto the client, using the useSession hook, but this isn't "ideal" since that causes loading states flickers, which im trying to avoid.

snow flint
snow flint
cyan fiber
# snow flint yea, as it's a server side cache and every user get's the same response, it coul...

Brilliant, thanks for the response.

Ideally I was hoping to continue to use auth() to fetch the session server side, I did notice that it was causing weird issues with my navbar, as you mention it does seem like it could have opened up some security issues.

Is it not possible to force different SSR rendered components into caching?

for example, i would love if <PublicNavBar/> was never cached (force static?), but Home was always cached (revalidate = 240), as an example.

If not, i'll switch to using cache for the Home page but start using the useSession hook to move the navbar logic onto the client.

glad moat
#

You can’t choose the rendering strategy per component level per se (you can kinda implement patterns to keep as much static and only make dynamic the very specific components/pages that need to be with stuff like PartialPrerendering and <Suspense>)

#

If you want a page to “never be cached” you need to mark that page individually or having it under a dynamic segment.

For page level configuration you need to export const dynamic = “force-dynamic” or make use of a dynamic API such as cookies, headers, params, searchParams

#

If you want the page to be static but be able to refresh after certain time what you need is export const revalidate = 240

#

As long as you keep your auth out of layout.tsx and do checks either in middleware or per page you’re good

snow flint
cyan fiber
#

Amazing, thanks guys!

#

going to try and get this implemented today.

snow flint
#

@cyan fiber keep us updated

cyan fiber
# snow flint <@622469622372892726> keep us updated

Thank you! I've got it all working by doing the following:

page.tsx

export const revalidate = 600;

export default async function Home() {
  await expensiveDbQuery...
  return (...)
}

layout.tsx: no caching and <PublicNavBar/> is a client component which uses useSession to fetch the client info.

export default function Layout({ children }: { children: React.ReactNode }) {
    return (
        <main className="flex min-h-screen flex-col xl:p-0">
            <PublicNavBar />
            {children}
            <PublicFooter />
        </main>
    );
}
dull pathBOT