Dynamic routes not being cached
Unanswered
rash3r posted this in #help-forum
rash3rOP
In nextjs using the pages router with dynamic pages it is possible to do something like this:
Basically, in this way the console.log("rendering") is executed only once at the moment the
Launching
However, I was not able to replicate this behaviour in any way via router apps.
I have tried setting all combinations of
All the tests I ran were through
pages/something/[id].tsxexport default Page = () => {
const router = useRouter();
console.log("rendering")
if (!router.isReady) return null;
const id = router.query.id;
return <Something id={id}/>.
}Basically, in this way the console.log("rendering") is executed only once at the moment the
next build command is launched.Launching
next start will no longer display this log, thus proving that on the server the code is executed one and only once at build time.However, I was not able to replicate this behaviour in any way via router apps.
I have tried setting all combinations of
dynamic and dynamicParams, I have tried both with the page as a server component and as a client component. I tried using useParams(). But the result was always the same: after launching next build and next start, every hard reload on the browser of the /something/<whatever-value> page triggered the console log on the server, so I assume that nothing is actually being cached.All the tests I ran were through
next build and next start, aware that next dev has different caching behaviour.20 Replies
@rash3r In nextjs using the pages router with dynamic pages it is possible to do something like this:
`pages/something/[id].tsx `
ts
export default Page = () => {
const router = useRouter();
console.log("rendering")
if (!router.isReady) return null;
const id = router.query.id;
return <Something id={id}/>.
}
Basically, in this way the console.log("rendering") is executed only once at the moment the `next build` command is launched.
Launching `next start` will no longer display this log, thus proving that on the server the code is executed one and only once at build time.
However, I was not able to replicate this behaviour in any way via router apps.
I have tried setting all combinations of `dynamic` and `dynamicParams`, I have tried both with the page as a server component and as a client component. I tried using `useParams()`. But the result was always the same: after launching `next build` and `next start`, every hard reload on the browser of the `/something/<whatever-value>` page triggered the console log on the server, so I assume that nothing is actually being cached.
All the tests I ran were through `next build` and `next start`, aware that `next dev` has different caching behaviour.
In the pages router, dynamic routes are still statically generated by default.
In the app router, dynamic routes are dynamically rendered by default. You need to generate the static params via generateStaticParams for it to become statically rendered.
In the app router, dynamic routes are dynamically rendered by default. You need to generate the static params via generateStaticParams for it to become statically rendered.
rash3rOP
Thank you for your help! @Ray @joulev
So you are saying there's no way to replicate the same exact behaviour using app router?
So you are saying there's no way to replicate the same exact behaviour using app router?
There is one. I’m busy rn so can’t answer yet, if tomorrow no one helps you yet then I’ll answer
@rash3r you can return an empty array from getStaticParams
it will use incremental rendering for your page, they will be cached
@Eric Burel it will use incremental rendering for your page, they will be cached
rash3rOP
Thank you for the suggestion! I implemented it and found that it effectively prevents dynamic rendering for each request. Instead, rendering and subsequent caching occur only upon the initial request for a new [id], which is quite beneficial.
Nonetheless, this approach differs from the behavior observed with the pages router:
- With the pages router, the
- On the other hand, when returning an empty array from generateStaticParams using the app router, rendering is triggered upon each request for a page associated with an uncached [id].
To provide more detail, my particular scenario involves a route like /something/[id]. The
Here is a simplified example:
From the example, it's clear that you don't need to use the id on the server at all. Unfortunately, I couldn't find any way to get the same results you get with the pages router unless you switch to using just one static route (
Nonetheless, this approach differs from the behavior observed with the pages router:
- With the pages router, the
Page is rendered only once, during the build process. (SSG)- On the other hand, when returning an empty array from generateStaticParams using the app router, rendering is triggered upon each request for a page associated with an uncached [id].
To provide more detail, my particular scenario involves a route like /something/[id]. The
id parameter, while not utilized server-side, is used on the client side through tanstack-query.Here is a simplified example:
app/something/[id]/page.tsximport { Something } from "components/something";
export const generateStaticParams = () => {
return [];
};
export const dynamic = "force-static";
export default Page = () => {
return (
<Something />
);
};components/something.tsx"use client";
import { useParams } from "next/navigation";
export const Something = () => {
const params = useParams();
const { data } = useSomething(params.id);
if (!data) return null;
return <div>{data}</div>;
};From the example, it's clear that you don't need to use the id on the server at all. Unfortunately, I couldn't find any way to get the same results you get with the pages router unless you switch to using just one static route (
something/[id]/page.tsx-> something/page.tsx) with query parameters instead. But, this isn't really the best way to go about it.this is a single page application paradigm
Next.js is not really keen on that
in means your page should be dynamic
the problem is that you can't do that because it would break the prerender of your client-side application
trying to wrap my head around your issue but what you ask is basically disabling SSR for a page of your next app
I feel like you need to accept that Next will cache each request id after a render
that's how static rendering is done in Next
if you want to go deeper, in the Page Router, "next export" would generate a file like [id].html
and you could have a proxy rewriting the URL "/foobar/42" to "/foobar/[id].html"
sadly, this is exactly the only feature that haven't yet been ported to the App Router
what you are trying to do is a bit similar to that but to my best knowledge you can't do that yet
it's equivalent to have a Singe Page Application on your "something/" route