Next.js Discord

Discord Forum

GenerateStaticParams does not 404 if route is not in the ones returned

Answered
Indian mackerel posted this in #help-forum
Open in Discord
Indian mackerelOP
i have a [type] page in my application root that has
export function generateStaticParams() {
    return [{ type: "languages" }, { type: "guides" }];
}

however if i go in /sajkdioasd i still get a page, i want to redirect to 404, how do i do that?
i also have
export const dynamicParams = false;
Answered by Indian mackerel
kinda solved i dont remember how
View full answer

133 Replies

what is your build log
@aardani what is your build log
Indian mackerelOP
Route (app)                                 Size     First Load JS
┌ ○ /                                       8.56 kB        93.4 kB
├ λ /_not-found                             0 B                0 B
├ ● /[type]                                 752 B          85.6 kB
├   ├ /linguaggi
├   └ /guide

this the part ur intrested in?
do you use server action in /[type]?
Indian mackerelOP
a what?
try adding export const dynamic = 'error' to throw an error if dynamic function is used
which usually is the culprit of converting something to a lambda route
Indian mackerelOP
in dev it still behaves correctly
lemme build
yes i get a build error
what does it say
Indian mackerelOP
Error occurred prerendering page "/linguaggi". Read more: https://nextjs.org/docs/messages/prerender-error
Error: Page with `dynamic = "error"` couldn't be rendered statically because it used `headers`.
complete log
there you go
if you want static page you can't access headers()...
static page are built without dependency of user data like headers or cookies
Indian mackerelOP
i have authorization headers but its not from the user, its just a server secret to avoid user accessing that route
a build-only route
(i have an express backend, not nextjs')
you can't protect an SSG route in server components. That would imply every request produces different html result which meant it would turn into SSR/lambda/request-time render
Try protecting it in middleware
Indian mackerelOP
i am not protecting it
i mean
this is the function
export async function getGroups() {
    const groupsData = await (
        await fetch(process.env.NEXT_PUBLIC_SERVER_URL + "/groups", {
            method: "GET",
            headers: {
                Authorization: process.env.SUPERSECRET,
            },
            cache: "force-cache",
            next: {
                tags: ["groups"],
            },
        })
    ).json();

    return groupsData;
}
and its used in the server component
is this used in client or server
bruh
do you want to cache the getGroups?
Indian mackerelOP
i think so
lemme explain
try removing headers: {} and see if the problem persists.
if you need protection we need to use some other way
Indian mackerelOP
i have this configuration
[type]/[group]/[post]
type is static (guide|linguaggi)
group and post are dynamic
i thought to cache the group request to avoid calling it 150 times if i have 150 posts (even with this code it runs once every post but i think thats a different issue)
you can't mix SSG with dynamic rendering currently
the staticity of a route is determine as one whole route and not per segment
@aardani try removing `headers: {}` and see if the problem persists. if you need protection we need to use some other way
Indian mackerelOP
same issue
Error occurred prerendering page "/guide". Read more: https://nextjs.org/docs/messages/prerender-error
Error: Page with `dynamic = "error"` couldn't be rendered statically because it used `headers`.
export async function getGroups() {
    const groupsData = await (
        await fetch(process.env.NEXT_PUBLIC_SERVER_URL + "/groups", {
            method: "GET",
            // headers: {
            //     Authorization: process.env.SUPERSECRET,
            // },
            cache: "force-cache",
            next: {
                tags: ["groups"],
            },
        })
    ).json();

    return groupsData;
}
[post] still uses headers but idk if thats an issue
yes thats an issue :/
like i said its computed as a whole
not per segment
Indian mackerelOP
ok
how do i protect that route then
you can use middleware.ts set at the same level as the app folder
Indian mackerelOP
wdym, i need to protect the backend endpoint
what do you mean by backend endpoint? which part do you need to protect?
Indian mackerelOP
the api.website.com/groups endpoint
@Indian mackerel the api.website.com/groups endpoint
Hmm does it not throw build error anymore?
im running out of ideas 🫠 but you could try using a custom fetcher to bypass Next's fetch wrapper
@aardani Hmm does it not throw build error anymore?
Indian mackerelOP
it still does but i think its because i still have other requests with headers
@Indian mackerel it still does but i think its because i still have other requests with headers
try replacing it with a custom fetcher like
import { fetch as fetch2 } from "undici"
try export const dynamic = 'force-static' too
@aardani try replacing it with a custom fetcher like ts import { fetch as fetch2 } from "undici"
Indian mackerelOP
shouldnt i remove all the headers from the requests?
(sorry for the delay in the response)
@Indian mackerel shouldnt i remove all the headers from the requests?
But then how are you going to authenticate to your Expres backend?
Indian mackerelOP
you said that with Headers i cannot generate static pages
ah
try adding { cache: 'force-cache' } along side with your auth-ed fetches
Indian mackerelOP
already had them in all of them
@aardani try `export const dynamic = 'force-static'` too
Indian mackerelOP
with this it does build succesfully
yay
so is it solved
Indian mackerelOP
yeah it is
still a little issue tho
the request should be cached but its not
it has like a lot of scenarios where it would be opted out
un such case i think ure out of luck with fetch().
The last resort is using unstable_cache()
Indian mackerelOP
cannot i override this?
but
wait
i removed headers
export async function getGroups() {
    const groupsData = await (
        await fetch(process.env.NEXT_PUBLIC_SERVER_URL + "/groups", {
            method: "GET",
            // headers: {
            //     Authorization: process.env.SUPERSECRET,
            // },
            cache: "force-cache",
            next: {
                tags: ["groups"],
            },
        })
    ).json();

    return groupsData;
}

this is the request, why is it not cached
@aardani it has like a lot of scenarios where it would be opted out
Indian mackerelOP
it does not meet any of this requirement
Try again without devtool open?
Indian mackerelOP
uh?
i know the request is not being cached because i am watching the server's log
the express server log
oh
Indian mackerelOP
yeah
bug?
i dont think so
I'm not sure, you had a lot of uncached fetch so its hard to keep track why its not being cached
make sure this is not checked
@aardani make sure this is not checked
Indian mackerelOP
i am not using devtools
now that i see its like its being cached only some times
lemme see a sec
also like
NEXT_PUBLIC_ is not necessary if ure fetching it in the server
Indian mackerelOP
no i am also using it in the client
thats why i have to use authorization headers
ah i see, my bad
Indian mackerelOP
same server, both client and server functionality
[=   ] - info Generating static pages (10/40)Failed to set fetch cache http://localhost:5000/groups TypeError: fetch failed
    at Object.fetch (node:internal/deps/undici/undici:11457:11) {
  cause: Error: read ECONNRESET
      at TCP.onStreamRead (node:internal/stream_base_commons:217:20)
      at TCP.callbackTrampoline (node:internal/async_hooks:130:17) {
    errno: -4077,
    code: 'ECONNRESET',
    syscall: 'read'
  }
}
does this mean that the request itself failed?
yeah :this_is_fine:
Indian mackerelOP
how can it fail
whose fault is that
its a whole separate issue that i can't tell
Indian mackerelOP
only some times tho
so its kinda ok
Indian mackerelOP
i reinserted all the headers in the requests and seems to be building anyways
Maybe its the build cache :v
Indian mackerelOP
i removed .next folder
and its actually refetching
strange
Indian mackerelOP
@aardani sorry for the ping, if i have getServerSession in my navbar will it not run correctly if the page is statically built?
it seems like it
those uses headers()
so thats ur main culprit..........................
Indian mackerelOP
how do i solve this?
can i have the page static and the navbar dynamic?
why not just dynamic website all the way?
you can still persists data in between request
i dont think using SSG or generateStaticParams fits your use case. Unless im missing the bigger picture
Indian mackerelOP
the posts pages can be static
except for the navbar
If you want auth-guarded page you will need to make the dynamic.

Unless you are willing to let go of the page auth guard and authenticate in the client instead,
i.e authenticate per components
Indian mackerelOP
u mean useSession?
100%
and SessionProvider
Indian mackerelOP
i prefer dynamic website
will it be really different from static performance-wise?
If you cache things properly and use stuff like Suspense to render fallback component when loading
then no difference almost no difference
dynamic website can still have the feel of SSG
thats the good thing about React18's suspense boundary
Indian mackerelOP
by dynamic i mean not static but still completely SSR
yes we are on the same page
@Indian mackerel now that i see its like its being cached only some times
Indian mackerelOP
i take this back, its not caching it anymore
i'll pass the authorization via body, should solve it right?
even without using getServerSession?
im mainly focusing on dynamic pages for now so i can't tell ifit will work or not in SSG/ISR 😦
@aardani even without using getServerSession?
Indian mackerelOP
i am not using getServrSession for requests
Indian mackerelOP
kinda solved i dont remember how
Answer