{"record":{"id":"2a9bc6ec0ea02ac8","repo":"withastro/astro","slug":"the-view-transitions-client-api-was-called-during","errorCode":null,"errorMessage":"The view transitions client API was called during a server side render. This may be unintentional as the navigate() function is expected to be called in response to user interactions. Please make sure that your usage is correct.","messagePattern":"The view transitions client API was called during a server side render\\. This may be unintentional as the navigate\\(\\) function is expected to be called in response to user interactions\\. Please make sure that your usage is correct\\.","errorType":"console","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/astro/src/transitions/router.ts","lineNumber":592,"sourceCode":"\t\t// This log doesn't make it worse than before, where we got error messages about uncaught exceptions, which can't be caught when the trigger was a click or history traversal.\n\t\t// Needs more investigation on root causes if errors still occur sporadically\n\t\tconst err = e as Error;\n\t\t// biome-ignore lint/suspicious/noConsole: allowed\n\t\tconsole.log('[astro]', err.name, err.message, err.stack);\n\t}\n}\n\nlet navigateOnServerWarned = false;\n\nexport async function navigate(href: string, options?: Options) {\n\tif (inBrowser === false) {\n\t\tif (!navigateOnServerWarned) {\n\t\t\t// instantiate an error for the stacktrace to show to user.\n\t\t\tconst warning = new Error(\n\t\t\t\t'The view transitions client API was called during a server side render. This may be unintentional as the navigate() function is expected to be called in response to user interactions. Please make sure that your usage is correct.',\n\t\t\t);\n\t\t\twarning.name = 'Warning';\n\t\t\tconsole.warn(warning);\n\t\t\tnavigateOnServerWarned = true;\n\t\t}\n\t\treturn;\n\t}\n\tawait transition('forward', originalLocation, new URL(href, location.href), options ?? {});\n}\n\nfunction onPopState(ev: PopStateEvent) {\n\tif (!transitionEnabledOnThisPage() && ev.state) {\n\t\t// The current page doesn't have View Transitions enabled\n\t\t// but the page we navigate to does (because it set the state).\n\t\t// Do a full page refresh to reload the client-side router from the new page.\n\t\tlocation.reload();\n\t\treturn;\n\t}\n\n\t// History entries without state are created by the browser (e.g. for hash links)\n\t// Our view transition entries always have state.","sourceCodeStart":574,"sourceCodeEnd":610,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/transitions/router.ts#L574-L610","documentation":"navigate() from the View Transitions client router is browser-only, but the router module can be imported during SSR (from component frontmatter, layouts, or shared utils). Calling it server-side does nothing except log this warning — an Error named 'Warning' instantiated for the stack trace, printed once thanks to the navigateOnServerWarned flag — then returns early.","triggerScenarios":"Invoking navigate() during server rendering: top-level in a shared module, inside .astro frontmatter, or in code paths that execute on both server and client (e.g. a nav utility imported by both).","commonSituations":"Programmatic navigation based on props or session state (should be a server redirect via Astro.redirect); a shared nav helper running during SSR; copying client router examples into frontmatter scripts.","solutions":["Guard the call: if (typeof window !== 'undefined') navigate('/target')","Move navigation into <script> blocks or event handlers, which only execute in the browser","For redirects decided at render time, return Astro.redirect('/target') from the page instead"],"exampleFix":"// before\nimport { navigate } from 'astro:transitions/client';\nnavigate('/dashboard'); // executes during SSR -> warning\n\n// after\nimport { navigate } from 'astro:transitions/client';\nif (typeof window !== 'undefined') navigate('/dashboard');\n// or, when decided at render time: return Astro.redirect('/dashboard');","handlingStrategy":"type-guard","validationCode":"import { navigate } from 'astro:transitions/client';\nconst inBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';\nif (inBrowser) navigate(href); // importing server-side is safe; calling is not","typeGuard":"const inBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';\nexport function safeNavigate(href: string, opts?: Options) {\n  if (!inBrowser) return; // SSR no-op instead of a warning\n  navigate(href, opts);\n}","tryCatchPattern":null,"preventionTips":["Keep navigate() calls inside <script> blocks or DOM event handlers, never frontmatter","Use Astro.redirect() for redirects decided during rendering","Route all router calls through one guarded helper in a client-only module"],"tags":["astro","view-transitions","client-router","ssr","browser-api"],"backgroundTag":"browser-api-on-server","analyzedSha":"52e6c34790cc8ac4e69e6135ace06049867e5c4a","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}