Next.js Discord

Discord Forum

Why does the Next.js App Router call the RSC API even when the page are statically generated?

Unanswered
Lagotto Romagnolo posted this in #help-forum
Open in Discord
Lagotto RomagnoloOP
I noticed that in App Router projects—unlike the Pages Router—it still makes RSC (React Server Component) API calls for SSG page.
For example, for a route like /test/[testNo]:

- Navigating to /test/123 triggers a request to rsc?=123
- Navigating to /test/234 then triggers another request to rsc?=234

(I used generateStaticParams and 'dynamic = 'force-static' to make sure and t's statically generated at build time.)

This feels odd because the page is statically generated. I would expect it to just use the pre-generated data instead of making a new API call each time—something like rsc?=test-[testNo] once, and reusing it.

Is there any way to avoid these unnecessary API calls?
I’m hoping to reduce traffic by skipping redundant requests when possible.

9 Replies

Lagotto RomagnoloOP
yep. generateStaticParams is correct.
The code snippet I’m using looks like this:
// /test/[testNo]/page.tsx
import {AsyncBoundary} from '@/shared/AsyncBoundary';
export default function Index() {
    return (
        <AsyncBoundary fallback={<div>loading</div>}>
            this is rendered at client!
        </AsyncBoundary>
    );
}
export async function generateStaticParams() {
    return [];
}

I'm returning an empty array from generateStaticParams for now (to make this page "SSG")
Lagotto RomagnoloOP
Yeah, true. Technically, I need to return everything up front to make it work as full SSG.

But the thing is, even when I do return all the values I want, it still makes RSC requests on the client side — like rsc?=12, rsc?=34 (once per /test/[testNo]), etc.
Ideally, I’d expect it to make that call only once — not per /test/[testNo], but just once, something like rsc?=test-testNo, similar to how the Pages Router only downloads a static page’s JS bundle once.
(or better yet, not at all if everything is already statically generated.)

I’m really concerned that if I have hundreds of pages (/test/1 to /test/100), each user will end up making hundreds of redundant RSC API calls to my App Router server.
When I use the Pages Router, the client never makes any rsc requests(i.e. internal api request) to my server — everything is truly static.
That’s why I was hoping to avoid the extra traffic from these API calls when using the App Router as well.
Lagotto RomagnoloOP
Here's what I’ve found:

What I want to achieve is SSG with dynamic routes.

In the Page Router, this just works thanks to Automatic Static Optimization.
Even when using the Next.js server, the generated pages are served as static files — meaning the client doesn’t need to make any internal revalidation calls (like ssr.json/ssg.json) on each request.

However, in the App Router, things aren’t as straightforward.
To use SSG with dynamic routes, you might need to explicitly use server. (not sure why they use it.. but they want to re-build on revalidation on the fly?)

And even then, the client makes at least one RSC (React Server Component) call on initial route load. (or soft navigation)

A possible workaround is using static exports,
but that’s not ideal — it requires setting up an additional web server just to serve the HTML/CSS/JS output from the Next.js build.