withastro/astro · error · AstroError
MissingIndexForInternationalizationError
MissingIndexForInternationalizationError
Error message
Could not find index page. A root index page is required in order to create a redirect to the index URL of the default locale. (`/${defaultLocale}`) What it means
With i18n routing strategy `pathname-prefix-always` (`routing.prefixDefaultLocale: true`, or domains-based always-prefix), every URL — including the default locale's — carries a locale prefix, so Astro must generate a root `/` → `/${defaultLocale}` redirect. That redirect needs a root index page to exist; if no route equals `/`, manifest creation throws `MissingIndexForInternationalization` with a hint pointing at your pages directory.
Solutions
- Create `src/pages/index.astro` (even a minimal redirect/landing page) at the project root pages dir
- If `/` should serve the default locale unprefixed, switch strategy: set `routing: { prefixDefaultLocale: false }` (pathname-prefix-other-locales)
- Verify the file lives at the exact `srcDir/pages` location shown in the error's hint
Example fix
# before — i18n with prefixDefaultLocale: true and no src/pages/index.astro
# after — option 1: add the root page
echo '<html><body>redirect target</body></html>' > src/pages/index.astro
# after — option 2: astro.config.mjs
i18n: { defaultLocale: 'en', routing: { prefixDefaultLocale: false } } Defensive patterns
Strategy: validation
Validate before calling
// Config sanity check: always-prefix i18n requires a root index page
import { existsSync } from 'node:fs';
const alwaysPrefix = config.i18n?.routing?.prefixDefaultLocale === true;
if (alwaysPrefix && !existsSync('src/pages/index.astro')) {
throw new Error('i18n pathname-prefix-always requires src/pages/index.astro');
} Prevention
- Create `src/pages/index.astro` in the same commit that enables `prefixDefaultLocale: true`
- Keep the root index out of `[locale]` folders — it must be a literal `/` route
- Decide the prefix strategy before structuring pages under locale folders
When it happens
Trigger: Configuring `i18n: { defaultLocale: 'en', routing: { prefixDefaultLocale: true } }` while `src/pages/index.astro` does not exist; deleting or renaming the root index during a redesign; moving the index inside a `[locale]` dynamic folder so no literal `/` route remains.
Common situations: Enabling always-prefixed locales on a site that previously served `/` directly; teams structuring all pages under `src/pages/[locale]/` and forgetting the root shim; fresh i18n adoption from the i18n guide without the index step.
Related errors
- MissingLocaleError
- i18nNoLocaleFoundInPath
- i18nNotEnabled
- IncorrectStrategyForI18n
- InvalidI18nMiddlewareConfiguration
AI-assisted analysis of withastro/astro@e294953aa8 (2026-08-18).
Data as JSON: /api/errors/c69995caabbc7f87.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/core/routing/create-manifest.ts:774
// Report route collisions
for (const [index, higherRoute] of routes.entries()) {
for (const lowerRoute of routes.slice(index + 1)) {
detectRouteCollision(higherRoute, lowerRoute, config, logger);
}
}
const i18n = settings.config.i18n;
if (i18n) {
const strategy = toRoutingStrategy(i18n.routing, i18n.domains);
// First we check if the user doesn't have an index page.
if (strategy === 'pathname-prefix-always') {
let index = routes.find((route) => route.route === '/');
if (!index) {
let relativePath = path.relative(
fileURLToPath(settings.config.root),
fileURLToPath(new URL('pages', settings.config.srcDir)),
);
throw new AstroError({
...MissingIndexForInternationalization,
message: MissingIndexForInternationalization.message(i18n.defaultLocale),
hint: MissingIndexForInternationalization.hint(relativePath),
});
}
}
createI18nFallbackRoutes(routes, i18n, config);
}
if (dev) {
// In SSR, a 404 route is injected in the App directly for some special handling,
// it must not appear in the manifest
ensure404Route({ routes });
}
if (dev || settings.buildOutput === 'server') {
injectImageEndpoint(settings, { routes }, dev ? 'dev' : 'build');
}View on GitHub (pinned to e294953aa8)