Next.js Discord

Discord Forum

Are GET route handlers (route.tsx) prefetched by Link in production?

Unanswered
Masai Lion posted this in #help-forum
Open in Discord
Masai LionOP
I woke up to a subtle bug today caused by a <Link> prefetching a GET route.tsx handler.
The handler logic delete some cookies and it's meant to be intentionally triggered by the user. I had the route in a <Link> href prop without the prefetch option specified.

The documentation for <Link> says:

Prefetch behavior depends on whether the route is static or dynamic. For static routes, the full route will be prefetched (including all its data). For dynamic routes, the partial route down to the nearest segment with a loading.js boundary will be prefetched.

I thought my route was dynamic because it manipulates cookies and therefore can’t be static. So my question is: what was wrong in my reasoning? Is this a bug in the prefetch behavior? Should I always treat GET route handlers as "static" an therefore prefetched?

Thanks

8 Replies

Original message was deleted
hi there, we do not permit AI-generated answers in this server
@joulev you should never use a GET route to mutate data. use a different http verb and a `<button>` instead of `<a>`/`<Link>`
Masai LionOP
Ok good not know but even next-intl does set a cookie by simply navigating to a certain link.
Is this a next.js specifc thing? Cause i've always seen Set-Cookie headers in GET reqs

Also this don't answer my question. Why is that route prefetch'd? Is it considered static by default because is a GET?
The problem is already fixed, i don't need a solution. I need an explanation
@Masai Lion Ok good not know but even next-intl does set a cookie by simply navigating to a certain link. Is this a next.js specifc thing? Cause i've always seen Set-Cookie headers in GET reqs Also this don't answer my question. Why is that route prefetch'd? Is it considered static by default because is a GET?
no i'm simply giving feedback that it is not a great idea to perform mutations in GET routes. logging in/out is a mutation, that's why you don't see /api/auth/login for example being GET.

Also this don't answer my question. Why is that route prefetch'd? Is it considered static by default because is a GET?
now this one i don't know for sure. it should not be prefetched, but it is – this is likely a bug. perhaps <Link> only recognises other pages for static/dynamic handling and didn't expect to be provided a route handler to its href. will need to dive into the source code to figure that out though.
@Masai Lion Your feedback is welcome, didn't mean to sound harsh. I know that mutations that changes server side state should not be performed in get handlers, but my case was more like a "preference" cookie. Pretty much like the NEXT_LOCALE language preference of next-intl Your second point is very helpful, i didn't know that Link was made exclusively for pages routes
oh i see. still yeah i think in the nextjs ecosystem, for this you are expected to use a server action instead, with cookies().delete() inside it. y'know, nextjs doing nextjs things. i even think for most apps you don't even need route handlers anymore unless those route handlers are for use by an external application/service
Your second point is very helpful, i didn't know that Link was made exclusively for pages routes
that was just speculation on my part, an educated guess based on past bugs that the framework has had. please don't take it as the truth, though i wouldn't be too surprised to find out it is the truth. that said it remains true that this is a bug indeed