{"record":{"id":"b5d98304d2504558","repo":"withastro/astro","slug":"missingmiddlewareforinternationalization","errorCode":"MissingMiddlewareForInternationalization","errorMessage":"Your configuration setting `i18n.routing: 'manual'` requires you to provide your own i18n `middleware` file.","messagePattern":"Your configuration setting `i18n\\.routing: 'manual'` requires you to provide your own i18n `middleware` file\\.","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/core/middleware/vite-plugin.ts","lineNumber":80,"sourceCode":"\t\t\t\tuserMiddlewareIsPresent = !!middlewareId;\n\t\t\t\tif (middlewareId) {\n\t\t\t\t\tresolvedMiddlewareId = middlewareId.id;\n\t\t\t\t\treturn MIDDLEWARE_RESOLVED_MODULE_ID;\n\t\t\t\t} else if (hasIntegrationMiddleware) {\n\t\t\t\t\treturn MIDDLEWARE_RESOLVED_MODULE_ID;\n\t\t\t\t} else {\n\t\t\t\t\treturn NOOP_MIDDLEWARE;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\tload: {\n\t\t\tfilter: {\n\t\t\t\tid: new RegExp(`^(${NOOP_MIDDLEWARE}|${MIDDLEWARE_RESOLVED_MODULE_ID})$`),\n\t\t\t},\n\t\t\tasync handler(id) {\n\t\t\t\tif (id === NOOP_MIDDLEWARE) {\n\t\t\t\t\tif (!userMiddlewareIsPresent && settings.config.i18n?.routing === 'manual') {\n\t\t\t\t\t\tthrow new AstroError(MissingMiddlewareForInternationalization);\n\t\t\t\t\t}\n\t\t\t\t\treturn { code: 'export const onRequest = (_, next) => next()' };\n\t\t\t\t}\n\t\t\t\tif (id === MIDDLEWARE_RESOLVED_MODULE_ID) {\n\t\t\t\t\tif (!userMiddlewareIsPresent && settings.config.i18n?.routing === 'manual') {\n\t\t\t\t\t\tthrow new AstroError(MissingMiddlewareForInternationalization);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst preMiddleware = createMiddlewareImports(settings.middlewares.pre, 'pre');\n\t\t\t\t\tconst postMiddleware = createMiddlewareImports(settings.middlewares.post, 'post');\n\n\t\t\t\t\tconst code = `\n\t\t\t\t${\n\t\t\t\t\tuserMiddlewareIsPresent\n\t\t\t\t\t\t? `import { onRequest as userOnRequest } from '${resolvedMiddlewareId}';`\n\t\t\t\t\t\t: ''\n\t\t\t\t}\nimport { sequence } from 'astro:middleware';","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/core/middleware/vite-plugin.ts#L62-L98","documentation":"Thrown by the middleware vite plugin's load handler for the NOOP_MIDDLEWARE virtual module when i18n.routing is set to 'manual' and the user has not provided a middleware file. With manual routing, Astro does not inject its own i18n middleware, so the user must supply src/middleware.{ts,js} that wires up locale detection/routing.","triggerScenarios":"Configuring astro.config with i18n.routing: 'manual' but having no src/middleware.ts file. When the bundler loads the NOOP_MIDDLEWARE module and detects no user middleware, it throws MissingMiddlewareForInternationalization.","commonSituations":"Switching i18n.routing from 'automatic' (or default) to 'manual' to customize locale handling but forgetting to create the middleware file; setting up i18n for the first time with manual routing.","solutions":["Create src/middleware.ts that defines and exports an onRequest handler (or sequences i18n middleware).","If you did not intend manual routing, change i18n.routing back to 'automatic' (or remove the setting).","Import and use Astro's i18n helpers (e.g. from astro:i18n) inside your middleware to implement routing manually."],"exampleFix":"// before - astro.config.mjs: i18n: { routing: 'manual' }, no middleware file\n\n// after - create src/middleware.ts\nimport { defineMiddleware } from 'astro:middleware';\nexport const onRequest = defineMiddleware((context, next) => {\n  // your locale detection/routing logic\n  return next();\n});","handlingStrategy":"validation","validationCode":"// Ensure a middleware file exists when i18n.routing is 'manual'.\nimport { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nconst hasMiddleware = existsSync(resolve('src/middleware.ts')) ||\n  existsSync(resolve('src/middleware.js'));\nif (config.i18n?.routing === 'manual' && !hasMiddleware) {\n  throw new Error('Create src/middleware.ts for manual i18n routing');\n}","typeGuard":"function requiresI18nMiddleware(config: { i18n?: { routing?: string } }, hasMiddlewareFile: boolean): boolean {\n  return config.i18n?.routing === 'manual' && !hasMiddlewareFile;\n}","tryCatchPattern":null,"preventionTips":["Create src/middleware.ts whenever i18n.routing is 'manual'.","Run a config sanity check in CI for the i18n+middleware pairing.","Document the requirement when enabling manual routing."],"tags":["i18n","middleware","config","build","vite"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}