# `` _(no submodules)_ ## Purpose `` 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: ```tsx import { TranslationProvider } from "@suaveplan/react-i18n"; import { MissingKeyOverlay } from "@suaveplan/react-i18n/components/missing-key-overlay"; ; ``` 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: ```tsx 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( , 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.