remix-run/react-router · error
You cannot use navigator.go() on the server because it is a
Error message
You cannot use navigator.go() on the server because it is a stateless environment. This error was probably triggered when you did a `navigate(${delta})` somewhere in your app. What it means
History jumps like navigate(-1) or navigate(2) map to navigator.go(delta), which throws on the SSR stateless navigator (lib/dom/server.tsx:283). A server render has no browser history stack to traverse, so any relative jump executed server-side is a bug.
Source
Thrown at packages/react-router/lib/dom/server.tsx:312
createHref,
encodeLocation,
push(to: To) {
throw new Error(
`You cannot use navigator.push() on the server because it is a stateless ` +
`environment. This error was probably triggered when you did a ` +
`\`navigate(${JSON.stringify(to)})\` somewhere in your app.`,
);
},
replace(to: To) {
throw new Error(
`You cannot use navigator.replace() on the server because it is a stateless ` +
`environment. This error was probably triggered when you did a ` +
`\`navigate(${JSON.stringify(to)}, { replace: true })\` somewhere ` +
`in your app.`,
);
},
go(delta: number) {
throw new Error(
`You cannot use navigator.go() on the server because it is a stateless ` +
`environment. This error was probably triggered when you did a ` +
`\`navigate(${delta})\` somewhere in your app.`,
);
},
back() {
throw new Error(
`You cannot use navigator.back() on the server because it is a stateless ` +
`environment.`,
);
},
forward() {
throw new Error(
`You cannot use navigator.forward() on the server because it is a stateless ` +
`environment.`,
);
},
};View on GitHub (pinned to 7aea711dd1)
Solutions
- Trigger delta navigation only from real user events (onClick), never during render or mount
- For logical back navigation, track an explicit route (from a query param or referrer) and use loader redirect instead
- Guard with an isBrowser check if the same code path can run on the server
Example fix
// before (runs on server render)
const navigate = useNavigate()
if (!search) navigate(-1)
// after (event-only)
<button onClick={() => navigate(-1)}>Go back</button> Defensive patterns
Strategy: validation
Validate before calling
const isServer = typeof window === 'undefined';
function goBack(navigate: NavigateFunction) {
if (isServer) return; // never jump history during SSR
navigate(-1);
} Prevention
- Trigger delta navigation only from real user events
- Track explicit return paths (query param/referrer) instead of history deltas for SSR-visible flows
- Audit shared components for mount-time history jumps
When it happens
Trigger: A back button implemented as <button onClick={...}> whose handler also runs during SSR render; navigate(-1) invoked in a component body or layout effect that executes on the server; shared components calling history-relative navigation on mount.
Common situations: 'Go back' UI rendered on the server that eagerly navigates; mobile-style flows using delta navigation on first render; effects ported from client-only apps into SSR components.
Related errors
- You cannot use navigator.back() on the server because it is
- You cannot use navigator.forward() on the server because it
- You cannot use navigator.push() on the server because it is
- You cannot use navigator.replace() on the server because it
- Prerender (data): Received a ${response.status} status code
AI-assisted analysis of remix-run/react-router@7aea711dd1 (2026-08-18).
Data as JSON: /api/errors/fc8410281ce2b6c5.
Report an issue: GitHub.