facebook/docusaurus · error

Can't find locale config for locale ${logger.code(localeToLo

Error message

Can't find locale config for locale ${logger.code(localeToLookFor)}

What it means

Thrown by getLocaleConfig() when looking up a locale in i18n.localeConfigs fails. The locale is either the one passed explicitly or, falling back, i18n.currentLocale. localeConfigs is populated from the i18n config in docusaurus.config.js, so a missing entry means the locale was referenced but never declared there.

Source

Thrown at packages/docusaurus-utils/src/i18nUtils.ts:76

  subPaths?: string[];
}): string {
  return path.join(
    localizationDir,
    // Make it convenient to use for single-instance
    // ie: return "docs", not "docs-default" nor "docs/default"
    `${pluginName}${pluginId === DEFAULT_PLUGIN_ID ? '' : `-${pluginId}`}`,
    ...subPaths,
  );
}

// TODO we may extract this to a separate package
//  we want to use it on the frontend too
//  but "docusaurus-utils-common" (agnostic utils) is not an ideal place since
export function getLocaleConfig(i18n: I18n, locale?: string): I18nLocaleConfig {
  const localeToLookFor = locale ?? i18n.currentLocale;
  const localeConfig = i18n.localeConfigs[localeToLookFor];
  if (!localeConfig) {
    throw new Error(
      `Can't find locale config for locale ${logger.code(localeToLookFor)}`,
    );
  }
  return localeConfig;
}

View on GitHub (pinned to 3f483e80e3)

Solutions

  1. Open docusaurus.config.js and confirm the failing locale code is present in both i18n.locales and i18n.localeConfigs (with at least label/direction/htmlLang entries).
  2. Match the exact casing and hyphenation of the locale code between the caller and the config (locale lookups are exact-string).
  3. If the locale should not be supported, fix the caller (URL switcher, plugin option) so it never requests that locale.
  4. Rebuild after saving the config change — localeConfigs is computed at config load time.

Example fix

// before (docusaurus.config.js)
i18n: {
  defaultLocale: 'en',
  locales: ['en'],
  localeConfigs: { en: { label: 'English' } }
}
// a request for /fr/ triggers the error

// after
i18n: {
  defaultLocale: 'en',
  locales: ['en', 'fr'],
  localeConfigs: {
    en: { label: 'English' },
    fr: { label: 'Français', direction: 'ltr', htmlLang: 'fr' }
  }
}
Defensive patterns

Strategy: validation

Validate before calling

function isLocaleConfigured(i18n: { localeConfigs: Record<string, unknown> }, locale?: string): boolean {
  const target = locale ?? (i18n as any).currentLocale;
  return Boolean(target && i18n.localeConfigs[target]);
}

if (!isLocaleConfigured(i18n, requestedLocale)) {
  throw new Error(`Locale '${requestedLocale}' is not declared in i18n.localeConfigs.`);
}

Type guard

function hasLocaleConfig(i18n: { localeConfigs: Record<string, unknown> }, locale: string): boolean {
  return locale in i18n.localeConfigs;
}

Try / catch

try {
  getLocaleConfig(i18n, locale);
} catch (err) {
  if (err instanceof Error && err.message.startsWith("Can't find locale config")) {
    // locale was requested but not configured; fall back to default or surface a helpful message
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling getLocaleConfig with a locale code that is not a key in i18n.localeConfigs. This happens when the URL or a plugin path forces a locale (e.g. /fr/) but the site's i18n.config only declares en. It also happens when i18n.currentLocale itself is set to a value not present in localeConfigs.

Common situations: Enabling localized routing before adding the locale to i18n.locales and i18n.localeConfigs. Typos in locale codes (e.g. 'en-US' vs 'en'). A plugin receiving a locale from a user-facing switcher that has not been configured. Upgrading Docusaurus and forgetting to migrate the i18n config shape.

Related errors


AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12). Data as JSON: /api/errors/5dd2536d349d8474. Report an issue: GitHub.