{"record":{"id":"111b7d64af71aa5c","repo":"withastro/astro","slug":"prerenderclientaddressnotavailable","errorCode":"PrerenderClientAddressNotAvailable","errorMessage":"`Astro.clientAddress` cannot be used inside prerendered route ${name}.","messagePattern":"`Astro\\.clientAddress` cannot be used inside prerendered route (.+?)\\.","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/core/fetch/fetch-state.ts","lineNumber":636,"sourceCode":"\t\t\tget csp() {\n\t\t\t\treturn state.getCsp();\n\t\t\t},\n\t\t\tget logger(): APIContext['logger'] {\n\t\t\t\treturn astroToRuntimeLogger(logger);\n\t\t\t},\n\t\t};\n\n\t\tthis.defineProviderGetters(partial);\n\n\t\treturn partial as Omit<AstroGlobal, 'props' | 'self' | 'slots'>;\n\t}\n\n\tgetClientAddress(): string {\n\t\tconst { clientAddress } = this;\n\t\tconst routeData = this.routeData!;\n\n\t\tif (routeData.prerender) {\n\t\t\tthrow new AstroError({\n\t\t\t\t...AstroErrorData.PrerenderClientAddressNotAvailable,\n\t\t\t\tmessage: AstroErrorData.PrerenderClientAddressNotAvailable.message(routeData.component),\n\t\t\t});\n\t\t}\n\n\t\tif (clientAddress) {\n\t\t\treturn clientAddress;\n\t\t}\n\n\t\tif (this.manifest.adapterName) {\n\t\t\tthrow new AstroError({\n\t\t\t\t...AstroErrorData.ClientAddressNotAvailable,\n\t\t\t\tmessage: AstroErrorData.ClientAddressNotAvailable.message(this.manifest.adapterName),\n\t\t\t});\n\t\t}\n\n\t\tthrow new AstroError(AstroErrorData.StaticClientAddressNotAvailable);\n\t}","sourceCodeStart":618,"sourceCodeEnd":654,"githubUrl":"https://github.com/withastro/astro/blob/e294953aa8aadd98d5be92e60a03037b05dbdfd4/packages/astro/src/core/fetch/fetch-state.ts#L618-L654","documentation":"FetchState.getClientAddress() checks routeData.prerender first and throws AstroErrorData.PrerenderClientAddressNotAvailable for prerendered routes. A prerendered route renders at build time, when no live request or client socket exists, so a client IP is conceptually unavailable — even when an adapter normally supplies one for server routes.","triggerScenarios":"Astro.clientAddress is accessed on a page that exports `const prerender = true` (or inherits prerendering from `output: 'static'`), including access from a shared component used by that page.","commonSituations":"Marking marketing pages prerendered for performance while they still log visitor IPs; migrating an app from SSR to hybrid/static output; a shared analytics component using Astro.clientAddress being added to a static page.","solutions":["Remove `export const prerender = true` from that route so it renders on demand","Move the IP-dependent logic (logging, geolocation, rate limiting) into a server endpoint or API route that is never prerendered","Guard the access so static and dynamic pages can share the component: only read clientAddress when not prerendered"],"exampleFix":"// before\nconst ip = Astro.clientAddress;\n\n// after\nconst ip = Astro.isPrerendered ? null : Astro.clientAddress;","handlingStrategy":"validation","validationCode":"const ip = import.meta.env.SSR && !Astro.isPrerendered ? Astro.clientAddress : null;\nif (ip === null) {\n  // skip IP-dependent work on prerendered pages\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep Astro.clientAddress out of components shared between static and dynamic pages","Centralize IP access in one helper that checks Astro.isPrerendered first","Put IP-dependent features in server endpoints/API routes that are never prerendered"],"tags":["client-address","prerender","static-generation","build-time"],"backgroundTag":"runtime-api-in-static-route","analyzedSha":"e294953aa8aadd98d5be92e60a03037b05dbdfd4","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}