how to detect client side navigation in RSC?
Answered
Polar bear posted this in #help-forum
Polar bearOP
I am trying to see if there is an "official" way to check if a user performd a client navigation to a page within the page's RSC. In the past, I have seen people check for the headers' next-url header but I don't see this header in next 16! Thanks 🙂
Answered by Azawakh
In Next.js 16, there is no official way to detect client navigation in an RSC.
The next-url header is unstable and often missing.
Best workaround:
Check for the _rsc query param using x-url header:
__
import { headers } from 'next/headers';
const isClientNav = new URL(headers().get('x-url')!).searchParams.has('_rsc');
__
true = client navigation (via <Link> or router.push)
false = hard refresh or direct visit
That’s the most reliable method today.
The next-url header is unstable and often missing.
Best workaround:
Check for the _rsc query param using x-url header:
__
import { headers } from 'next/headers';
const isClientNav = new URL(headers().get('x-url')!).searchParams.has('_rsc');
__
true = client navigation (via <Link> or router.push)
false = hard refresh or direct visit
That’s the most reliable method today.
7 Replies
@Polar bear I am trying to see if there is an "official" way to check if a user performd a client navigation to a page within the page's RSC. In the past, I have seen people check for the headers' next-url header but I don't see this header in next 16! Thanks 🙂
Azawakh
In Next.js 16, there is no official way to detect client navigation in an RSC.
The next-url header is unstable and often missing.
Best workaround:
Check for the _rsc query param using x-url header:
__
import { headers } from 'next/headers';
const isClientNav = new URL(headers().get('x-url')!).searchParams.has('_rsc');
__
true = client navigation (via <Link> or router.push)
false = hard refresh or direct visit
That’s the most reliable method today.
The next-url header is unstable and often missing.
Best workaround:
Check for the _rsc query param using x-url header:
__
import { headers } from 'next/headers';
const isClientNav = new URL(headers().get('x-url')!).searchParams.has('_rsc');
__
true = client navigation (via <Link> or router.push)
false = hard refresh or direct visit
That’s the most reliable method today.
Answer
Polar bearOP
Thanks. is this only available in prod build?
const headersList = await headers()
console.log(headersList.get('x-url'))
doing this in RSC results in null for the console.log in link or router.push client navigations O_O
const headersList = await headers()
console.log(headersList.get('x-url'))
doing this in RSC results in null for the console.log in link or router.push client navigations O_O
Azawakh
In dev mode, x-url is usually null — normal.
It works only in production (next build && next start).
In production, _rsc in x-url → client navigation.
No _rsc → hard reload/direct visit.
It works only in production (next build && next start).
In production, _rsc in x-url → client navigation.
No _rsc → hard reload/direct visit.
what about the sec-fetch-dest header?
or is it already outdated
Polar bearOP
gotcha thanks sunny!
@Polar bear gotcha thanks sunny!
Azawakh
@Polar bear Can you help me please?