Files
skills/docs/localization/i18n/react-i18n/src/components/missing-key-overlay/missing-key-overlay.md
2026-05-29 08:20:56 +01:00

3.9 KiB

<MissingKeyOverlay>

(no submodules)

Purpose

<MissingKeyOverlay> is a dev-mode visual diagnostic that surfaces every missingKey event emitted by the active I18nInstance as a fixed-position list anchored to the bottom-right corner of the viewport. The overlay gives engineers a passive, always-on view of translation gaps as they develop — no console-tab toggling, no debug flag, no polling. In production builds the component renders null and registers no event listener so it costs nothing once shipped.

Features

  • Subscribes to missingKey events on the Provider's instance bus
  • Renders a fixed-position list with aria-live="polite" so screen readers announce new entries without focus theft
  • Caps retained entries at the most-recent maxEntries (default 50); older entries silently drop off
  • Returns null in production (process.env.NODE_ENV === 'production')
  • Returns null when no Provider is mounted yet (no listener leak)
  • Ergonomic style defaults (monospace, dark background) plus per-entry locale and namespace meta

Usage: Basic Example

Mount the overlay once near the root of the application — it auto-tracks every miss for the lifetime of the active Provider:

import { TranslationProvider } from "@suaveplan/react-i18n";
import { MissingKeyOverlay } from "@suaveplan/react-i18n/components/missing-key-overlay";

<TranslationProvider config={i18nConfig}>
    <App />
    <MissingKeyOverlay />
</TranslationProvider>;

In dev, every t('absent.key') call appears in the overlay. In a production bundle the component compiles to a no-op return.

Usage: Advanced Example

A custom cap with explicit prod override and a portal mount so the overlay sits in a dedicated DOM root:

import { createPortal } from "react-dom";
import { MissingKeyOverlay } from "@suaveplan/react-i18n/components/missing-key-overlay";

function DiagnosticsPortal() {
    const root = document.getElementById("diagnostics-root");
    if (!root) return null;
    return createPortal(
        <MissingKeyOverlay
            // Force the overlay on even in a prod build for QA staging
            production={false}
            maxEntries={200}
        />,
        root
    );
}

API Reference

MissingKeyOverlay(props?: MissingKeyOverlayProps): ReactElement | null

Props:

  • maxEntries?: number — hard cap on retained entries. Default: 50.
  • production?: boolean — override for the runtime env-check. When true, the component returns null and does not subscribe.

Returns: null in production, when no Provider ancestor is mounted, or when no missingKey events have fired yet. Otherwise returns the fixed-position overlay.

MissingKeyEntry

  • id: number — monotonically increasing counter (used as React key)
  • key: string — the missing translation key
  • locale: string — locale at the moment the event was observed
  • namespace: string — namespace label (empty string when no namespace)

Implementation Notes

  • The component uses useEffect (not useSyncExternalStore) for the bus subscription because the entry list is a piece of internal React state driven by the bus rather than a snapshot of an external store. The two patterns are interchangeable here, and useEffect is simpler to reason about for a buffer with bounded capacity.
  • The append-and-cap helper (appendCapped) does the slice work outside the React update so the overlay never re-allocates the entire history on every event — only the bounded tail.
  • The fixed-position styles are applied inline so the overlay is self-contained: no external CSS file, no Tailwind dependency, no risk of the host app's stylesheet hiding it.
  • The production prop exists to make the prod-path testable without mutating process.env.NODE_ENV. The default reads isProductionEnv() on every render so consumers do not need to thread the flag through manually in their own builds.