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

  1. Create `src/pages/index.astro` (even a minimal redirect/landing page) at the project root pages dir
  2. If `/` should serve the default locale unprefixed, switch strategy: set `routing: { prefixDefaultLocale: false }` (pathname-prefix-other-locales)
  3. 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

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


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)