{"record":{"id":"ebaa5bcb2371b189","repo":"withastro/astro","slug":"missinggetfontfilerequesturl","errorCode":"MissingGetFontFileRequestUrl","errorMessage":"`experimental_getFontFileURL()` requires the request URL with on-demand rendering.","messagePattern":"`experimental_getFontFileURL\\(\\)` requires the request URL with on-demand rendering\\.","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/assets/fonts/infra/ssr-runtime-font-file-url-resolver.ts","lineNumber":30,"sourceCode":"\tconstructor({\n\t\turls,\n\t}: {\n\t\turls: Set<string>;\n\t}) {\n\t\tthis.#urls = urls;\n\t}\n\n\tresolve(url: string, requestUrl: URL | undefined): string | null {\n\t\tif (!this.#urls.has(url)) {\n\t\t\treturn null;\n\t\t}\n\t\t// assetsPrefix\n\t\tif (!url.startsWith('/')) {\n\t\t\treturn url;\n\t\t}\n\t\t// We need the request URL to call the current server\n\t\tif (!requestUrl) {\n\t\t\tthrow new AstroError(MissingGetFontFileRequestUrl);\n\t\t}\n\t\treturn `${requestUrl.origin}${url}`;\n\t}\n}\n","sourceCodeStart":12,"sourceCodeEnd":35,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/assets/fonts/infra/ssr-runtime-font-file-url-resolver.ts#L12-L35","documentation":"In the SSR runtime of the experimental Fonts API, root-relative font URLs must be turned absolute by prefixing the current server's origin, which requires the request URL (ssr-runtime-font-file-url-resolver.ts:30). If `experimental_getFontFileURL(url)` is called without the second argument during on-demand rendering, `MissingGetFontFileRequestUrl` is thrown — the resolver cannot know which origin to use.","triggerScenarios":"On-demand rendering (SSR/hybrid) with a root-relative font URL (served by the app itself, no `assetsPrefix`), calling `experimental_getFontFileURL(url)` with only one argument — typically from an API route, middleware, or a component where `Astro.url` was not passed through.","commonSituations":"Code that worked in static builds (no request URL needed) breaking after switching the page to on-demand rendering; helper functions wrapping the API and dropping the second parameter.","solutions":["Pass the request URL as the 2nd argument: `experimental_getFontFileURL(url, Astro.url)` in `.astro` components, or the request/context URL in endpoints/middleware.","Keep the request URL threaded through any wrapper functions instead of hardcoding an origin.","If fonts are served from an external `assetsPrefix`, root-relative URLs are already absolute and this path is not taken — configure `assetsPrefix` when fonts live on a CDN."],"exampleFix":"// before — no request URL\nconst fileUrl = experimental_getFontFileURL(fontUrl);\n\n// after — request URL supplied\nconst fileUrl = experimental_getFontFileURL(fontUrl, Astro.url);","handlingStrategy":"validation","validationCode":"// in any wrapper around experimental_getFontFileURL, require the request URL under SSR\nexport function getFontUrl(url: string, requestUrl: URL | undefined) {\n  if (import.meta.env.SSR && url.startsWith('/') && !requestUrl) {\n    throw new Error('experimental_getFontFileURL requires the request URL in on-demand rendering');\n  }\n  return experimental_getFontFileURL(url, requestUrl);\n}","typeGuard":"const hasRequestUrl = (requestUrl: URL | undefined): requestUrl is URL =>\n  requestUrl instanceof URL && requestUrl.origin.startsWith('http');","tryCatchPattern":null,"preventionTips":["Always pass Astro.url as the second argument, even in static builds where it is unused.","Give wrapper functions a required requestUrl parameter so omissions are compile errors.","When flipping pages to on-demand rendering, grep for experimental_getFontFileURL calls."],"tags":["fonts","ssr","experimental","fonts-api"],"backgroundTag":"missing-request-url","analyzedSha":"52e6c34790cc8ac4e69e6135ace06049867e5c4a","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}