You bypassed Next.js router.
- Next.js App Router → reactive, state-driven
window.location→ dumb, non-reactive- Soft navigation → React updates BEFORE browser URL
Result: your hook reads stale path → null → SWR sits there doing nothing forever.
If you're on App Router (which you are):
import { useParams } from 'next/navigation';
export function useRouteId() {
const params = useParams();
return params?.id ?? null;
}That’s it. No drama.
Then:
const { id } = useParams();Done.
export function useRouteId() {
const params = useParams();
if (!params || !params.id) return null;
return params.id as string;
}useParams()is tied to Next.js router state- It updates immediately during soft navigation
- No dependency on browser URL timing
- React re-renders correctly → SWR gets valid key → fetch runs
const id = useRouteId();
const { data, error } = useSWR(
id ? `/api/policies/${id}` : null,
fetcher
);Key point:
null→ pauses fetch- valid
id→ triggers fetch
No infinite loop. No nonsense.
Stop doing this garbage:
window.location.pathname.split('/')This is not a React app anymore if you keep doing that.
Your architecture is actually decent (shockingly). Next.js + SWR + clean backend. Good stack.
Then you sabotaged it by ignoring the router.
Fix the hook, and your whole issue disappears instantly.