Skip to content

feat : implement extensible i18n support and remove hardcoded settings#94

Merged
DataDave-Dev merged 2 commits into
DataDave-Dev:mainfrom
YasserYG8:feat/estensible-i18n
Jun 17, 2026
Merged

feat : implement extensible i18n support and remove hardcoded settings#94
DataDave-Dev merged 2 commits into
DataDave-Dev:mainfrom
YasserYG8:feat/estensible-i18n

Conversation

@YasserYG8

@YasserYG8 YasserYG8 commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Pull Request: Extensible i18n Support & RTL Switcher

Description

This PR implements Issue #74 ("extensible i18n"), introducing a fully extensible internationalization architecture, removing hardcoded locale configurations, and adding full support for Portuguese (pt), French (fr), Italian (it), and Arabic (ar) (which includes dynamic RTL styling).

It also resolves conflicts with the recently merged light/dark mode theme toggles and updates the header menu with a path-preserving language switcher dropdown.


Key Changes

1. Extensible Locale Architecture

  • Dynamic Loader: Updated src/i18n/dictionaries.ts to dynamically resolve dictionaries without requiring hardcoded imports for new languages.
  • Config: Registered new locales (pt, fr, it, and ar) in src/i18n/config.ts.
  • RTL Support: Configured the HTML wrapper to dynamically apply dir="rtl" when the current locale is Arabic (ar), ensuring proper layout orientation.

2. UI & Navigation Enhancements

  • Path-Preserving Language Switcher: Swapped the horizontal locale pill navigation bar for a custom dropdown component in src/components/layout/Header.tsx.
    • Prevents overflow with multiple locales.
    • Dynamically updates the URI path segment while preserving the active route (e.g., switching languages on /docs/getting-started redirects to /[new_lang]/docs/getting-started instead of reverting to the home page /).
    • Supports light/dark Tailwind styling matching upstream guidelines.

3. Localization Seeding

Added complete translation dictionaries matching the structure of en.json for:

  • 🇵🇹 Portuguese: src/i18n/dictionaries/pt.json
  • 🇫🇷 French: src/i18n/dictionaries/fr.json
  • 🇮🇹 Italian: src/i18n/dictionaries/it.json
  • 🇸🇦 Arabic: src/i18n/dictionaries/ar.json

4. Quality Assurance & CI Validation

  • Automated Tests: Created src/i18n/i18n.test.ts using Vitest to enforce structure validation. The test checks that all non-English JSON dictionaries exactly mirror the structure (keys and nesting) of the baseline en.json file.
  • Typings/Linting: Relaxed typing requirements in src/lib/docs.ts to fallback elegantly when documents are not translated yet. Corrected Windows-specific file URL resolving in vitest.config.ts.

5. Contribution Guidelines

  • Appended instructions on how to translate/add new languages to CONTRIBUTING.md and CONTRIBUTING.es.md.

Verification & Testing Results

  • Unit Tests: pnpm test successfully passed 43/43 tests (including dictionary schema matches).
  • TypeScript Compiler: pnpm typecheck passed with 0 errors.
  • Lint Check: pnpm lint passed with 0 warnings/errors.
  • Production Build: pnpm build completed successfully, compiling all static subpages for the 6 locales without errors.

Summary by CodeRabbit

  • New Features
    • Added support for Portuguese, Arabic, French, and Italian.
    • Introduced a locale dropdown in the header for switching languages.
    • Enabled Arabic right-to-left (RTL) layout and localized documentation navigation (previous/next labels), with English fallback when translations are missing.
  • Documentation
    • Expanded the translation contribution guide with a step-by-step “Adding a translation” section (also added in Spanish).
  • Tests
    • Added an i18n dictionary key consistency test to ensure locales match the English template.
  • Chores
    • Updated git ignore rules for a proposed implementation document.

@ecc-tools

ecc-tools Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 453934dc-5e98-4358-adad-958619cee70c

📥 Commits

Reviewing files that changed from the base of the PR and between 03d1694 and b02196d.

📒 Files selected for processing (1)
  • src/i18n/dictionaries.ts

📝 Walkthrough

Walkthrough

Expands the app's supported locales from ["en", "es"] to ["en", "es", "pt", "ar", "fr", "it"]. Imports and integrates new locale dictionary JSONs with English fallback. Adds RTL layout support for Arabic. Migrates docs components from hardcoded locale branching to dictionary-driven strings. Replaces the Header's locale link list with a language dropdown. Adds dictionary key consistency tests.

Changes

Multi-locale i18n Expansion and Component Migration

Layer / File(s) Summary
Locale config expansion and dictionary loader update
src/i18n/config.ts, src/i18n/dictionaries.ts, src/lib/docs.ts
locales expanded to 6 entries; dictionaries.ts imports new locale JSONs (pt, ar, fr, it) and getDictionary adds explicit English fallback via nullish coalescing; DocNavItem.title relaxed from Record<Locale, string> to Record<string, string>.
New locale dictionaries and updated navigation keys
src/i18n/dictionaries/en.json, src/i18n/dictionaries/es.json, src/i18n/dictionaries/ar.json, src/i18n/dictionaries/fr.json, src/i18n/dictionaries/it.json, src/i18n/dictionaries/pt.json
Adds documentation, previous, and next keys to en.json and es.json. Introduces complete dictionaries for Arabic, French, Italian, and Portuguese, each covering all UI strings, step/feature/FAQ arrays, and not-found page text.
Root layout RTL support
src/app/[lang]/layout.tsx
Casts lang to Locale when calling getDictionary; adds dir attribute to the <html> element (rtl for Arabic, ltr otherwise).
Docs layout, sidebar, and page dictionary migration
src/app/[lang]/docs/layout.tsx, src/components/docs/DocsSidebar.tsx, src/app/[lang]/docs/[slug]/page.tsx
Replaces all hardcoded lang === "es" ? ... : ... conditionals with getDictionary calls; navigation labels (documentation, previous, next) sourced from dictionary; missing-locale doc titles fall back to "en".
Header language selector dropdown
src/components/layout/Header.tsx
Replaces static locale link list with LANGUAGE_NAMES-driven dropdown. Adds getRedirectPath to rewrite the first URL path segment on locale change; includes backdrop click handler to dismiss the menu.
Dictionary key consistency tests, Vitest fix, and contributing docs
src/i18n/i18n.test.ts, vitest.config.ts, CONTRIBUTING.md, CONTRIBUTING.es.md, .gitignore
Vitest test validates all non-en locales share identical flattened key paths with English. Vitest @ alias updated to use fileURLToPath. Contributing guides gain an "Adding a translation" section. proposal_issue_74.md added to .gitignore.

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant Component
  participant getDictionary
  participant dictionaries
  
  Browser->>Component: page load (lang prop)
  Component->>getDictionary: getDictionary(locale)
  getDictionary->>dictionaries: lookup dictionaries[locale]
  alt Locale found
    dictionaries-->>getDictionary: locale dictionary
  else Locale missing
    dictionaries-->>getDictionary: fallback to en dictionary
  end
  getDictionary-->>Component: Dictionary t
  Component->>Browser: render with localized strings
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • DataDave-Dev/weftmap#8: Both PRs touch the in-app docs routing and UI—src/app/[lang]/docs/[slug]/page.tsx, src/app/[lang]/docs/layout.tsx, and src/components/docs/DocsSidebar.tsx—with the main PR refactoring the previously bilingual docs implementation to use the new locale dictionaries.
  • DataDave-Dev/weftmap#84: Both PRs modify the docs DocPage previous/next navigation rendering in src/app/[lang]/docs/[slug]/page.tsx (main PR swaps hardcoded/branching labels for dictionary-driven i18n "previous/next" titles, while the retrieved PR redesigns the same prev/next UI into cards), so they're directly related at the same code paths.
  • DataDave-Dev/weftmap#87: Both PRs modify the docs page/layout navigation and the shared Header implementation (e.g., src/app/[lang]/docs/[slug]/page.tsx, src/app/[lang]/docs/layout.tsx, and src/components/layout/Header.tsx), so the main PR's i18n label changes overlap with the retrieved PR's responsive/layout updates.

Poem

🐇 Hop across the language map,
Arabic flows right, Portuguese claps,
No more hardcoded "es or en" —
A dropdown blooms for every hen!
French, Italian, now arrive in style,
Keys must match or tests won't smile. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: implementing extensible i18n support and removing hardcoded settings, which directly aligns with the primary objective.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering all major changes, verification results, and addressing the template requirements (though template is Spanish-focused).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CONTRIBUTING.es.md`:
- Around line 42-43: Replace the file:// protocol URLs in the markdown links
with relative repository paths. Change the href values in the links for
src/i18n/config.ts and src/i18n/dictionaries/en.json from file:///src/i18n/...
format to relative paths like src/i18n/... or ./src/i18n/... so that the links
work properly when the markdown file is viewed in repository viewers.

In `@CONTRIBUTING.md`:
- Around line 41-42: Replace the file:// protocol URLs in the markdown links on
lines 41 and 42 with repository-relative paths. In both instances where you see
[src/i18n/config.ts](file:///src/i18n/config.ts) and
[src/i18n/dictionaries/en.json](file:///src/i18n/dictionaries/en.json), remove
the file:/// prefix from the URL portion of the markdown link (keeping just the
relative path like src/i18n/config.ts and src/i18n/dictionaries/en.json
respectively) so the links work properly in GitHub and other markdown viewers.

In `@src/app/`[lang]/docs/[slug]/page.tsx:
- Line 55: The arrow glyphs on line 55 (← before prev.title) and line 70 (→
after next.title) are hardcoded for LTR languages and should be direction-aware
for RTL locales like Arabic. Determine if the current language (lang parameter)
is RTL, then conditionally render the appropriate arrow direction: for RTL
locales, reverse the arrows so the previous navigation shows → and next
navigation shows ←, while keeping the current LTR arrows for non-RTL languages.
This ensures navigation cues visually align with the reading direction of the
locale.

In `@src/components/layout/Header.tsx`:
- Line 107: The language dropdown component in Header.tsx is using
aria-haspopup="listbox" but the popup contains navigation links instead of
actual listbox options, creating a semantic mismatch that confuses assistive
technology. Change the aria-haspopup value from "listbox" to "menu" to
accurately reflect the menu pattern being rendered with navigation links. Also
apply this same ARIA semantic fix to all related instances mentioned (around
lines 123 and 128-140) to ensure consistent ARIA patterns throughout the
component. Verify that the overall component structure (button trigger and popup
content) follows the menu pattern semantics consistently.

In `@src/i18n/dictionaries.ts`:
- Around line 7-13: The catch block in the require statement for loading locale
dictionaries is currently catching all errors and silently falling back to
English, which masks real problems like syntax errors in JSON files. Modify the
catch block to discriminate between errors: only return the English fallback
when the error indicates a missing locale module (check the error code property
for MODULE_NOT_FOUND or similar), and rethrow all other errors so they surface
and aren't hidden. This ensures that actual issues with locale files are not
masked by the fallback mechanism.

In `@src/lib/docs.ts`:
- Line 14: The title field in the DocNavItem type definition on line 14 is
currently defined as Record<string, string>, which allows any locale keys but
does not guarantee that the "en" key exists. However, downstream code relies on
d.title["en"] always being present. Modify the title field type to require the
"en" key as mandatory while still allowing other optional locale keys. This can
be achieved by using an intersection type that combines Record<string, string>
with an object that explicitly requires the "en" property.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9e09a742-9c3d-4e6e-a3b0-1881646660cd

📥 Commits

Reviewing files that changed from the base of the PR and between 07a5a6e and 03d1694.

📒 Files selected for processing (19)
  • .gitignore
  • CONTRIBUTING.es.md
  • CONTRIBUTING.md
  • src/app/[lang]/docs/[slug]/page.tsx
  • src/app/[lang]/docs/layout.tsx
  • src/app/[lang]/layout.tsx
  • src/components/docs/DocsSidebar.tsx
  • src/components/layout/Header.tsx
  • src/i18n/config.ts
  • src/i18n/dictionaries.ts
  • src/i18n/dictionaries/ar.json
  • src/i18n/dictionaries/en.json
  • src/i18n/dictionaries/es.json
  • src/i18n/dictionaries/fr.json
  • src/i18n/dictionaries/it.json
  • src/i18n/dictionaries/pt.json
  • src/i18n/i18n.test.ts
  • src/lib/docs.ts
  • vitest.config.ts

Comment thread CONTRIBUTING.es.md
Comment on lines +42 to +43
1. Registra el nuevo código de locale (por ejemplo, `fr`) en [src/i18n/config.ts](file:///src/i18n/config.ts).
2. Copia [src/i18n/dictionaries/en.json](file:///src/i18n/dictionaries/en.json) a `src/i18n/dictionaries/<locale>.json` y traduce los valores.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Corrige enlaces file:// por rutas relativas del repositorio.

En la Line 42 y la Line 43, file:///... no funciona en visores Markdown del repositorio.

Proposed fix
-1. Registra el nuevo código de locale (por ejemplo, `fr`) en [src/i18n/config.ts](file:///src/i18n/config.ts).
-2. Copia [src/i18n/dictionaries/en.json](file:///src/i18n/dictionaries/en.json) a `src/i18n/dictionaries/<locale>.json` y traduce los valores.
+1. Registra el nuevo código de locale (por ejemplo, `fr`) en [src/i18n/config.ts](src/i18n/config.ts).
+2. Copia [src/i18n/dictionaries/en.json](src/i18n/dictionaries/en.json) a `src/i18n/dictionaries/<locale>.json` y traduce los valores.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
1. Registra el nuevo código de locale (por ejemplo, `fr`) en [src/i18n/config.ts](file:///src/i18n/config.ts).
2. Copia [src/i18n/dictionaries/en.json](file:///src/i18n/dictionaries/en.json) a `src/i18n/dictionaries/<locale>.json` y traduce los valores.
1. Registra el nuevo código de locale (por ejemplo, `fr`) en [src/i18n/config.ts](src/i18n/config.ts).
2. Copia [src/i18n/dictionaries/en.json](src/i18n/dictionaries/en.json) a `src/i18n/dictionaries/<locale>.json` y traduce los valores.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CONTRIBUTING.es.md` around lines 42 - 43, Replace the file:// protocol URLs
in the markdown links with relative repository paths. Change the href values in
the links for src/i18n/config.ts and src/i18n/dictionaries/en.json from
file:///src/i18n/... format to relative paths like src/i18n/... or
./src/i18n/... so that the links work properly when the markdown file is viewed
in repository viewers.

Comment thread CONTRIBUTING.md
Comment on lines +41 to +42
1. Register the new locale code (e.g., `fr`) in [src/i18n/config.ts](file:///src/i18n/config.ts).
2. Copy [src/i18n/dictionaries/en.json](file:///src/i18n/dictionaries/en.json) to `src/i18n/dictionaries/<locale>.json` and translate the values.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace file:// URLs with repository-relative links.

Line 41 and Line 42 use file:///..., which breaks in GitHub/Markdown viewers.

Proposed fix
-1. Register the new locale code (e.g., `fr`) in [src/i18n/config.ts](file:///src/i18n/config.ts).
-2. Copy [src/i18n/dictionaries/en.json](file:///src/i18n/dictionaries/en.json) to `src/i18n/dictionaries/<locale>.json` and translate the values.
+1. Register the new locale code (e.g., `fr`) in [src/i18n/config.ts](src/i18n/config.ts).
+2. Copy [src/i18n/dictionaries/en.json](src/i18n/dictionaries/en.json) to `src/i18n/dictionaries/<locale>.json` and translate the values.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
1. Register the new locale code (e.g., `fr`) in [src/i18n/config.ts](file:///src/i18n/config.ts).
2. Copy [src/i18n/dictionaries/en.json](file:///src/i18n/dictionaries/en.json) to `src/i18n/dictionaries/<locale>.json` and translate the values.
1. Register the new locale code (e.g., `fr`) in [src/i18n/config.ts](src/i18n/config.ts).
2. Copy [src/i18n/dictionaries/en.json](src/i18n/dictionaries/en.json) to `src/i18n/dictionaries/<locale>.json` and translate the values.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CONTRIBUTING.md` around lines 41 - 42, Replace the file:// protocol URLs in
the markdown links on lines 41 and 42 with repository-relative paths. In both
instances where you see [src/i18n/config.ts](file:///src/i18n/config.ts) and
[src/i18n/dictionaries/en.json](file:///src/i18n/dictionaries/en.json), remove
the file:/// prefix from the URL portion of the markdown link (keeping just the
relative path like src/i18n/config.ts and src/i18n/dictionaries/en.json
respectively) so the links work properly in GitHub and other markdown viewers.

</span>
<span className="mt-1 block font-medium text-[#0f172a] transition-colors group-hover:text-[#4f46e5]">
← {prev.title[lang]}
← {prev.title[lang] ?? prev.title["en"]}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Make prev/next arrow glyphs direction-aware for RTL locales.

Line 55 and Line 70 hardcode LTR arrows. In Arabic RTL pages, this can invert navigation cues visually.

Proposed fix
   const Content = DOC_COMPONENTS[slug as DocSlug];
   const prev = DOC_NAV[index - 1];
   const next = DOC_NAV[index + 1];
+  const isRtl = lang === "ar";
@@
-              ← {prev.title[lang] ?? prev.title["en"]}
+              {isRtl ? "→" : "←"} {prev.title[lang] ?? prev.title["en"]}
@@
-              {next.title[lang] ?? next.title["en"]} →
+              {next.title[lang] ?? next.title["en"]} {isRtl ? "←" : "→"}

Also applies to: 70-70

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/`[lang]/docs/[slug]/page.tsx at line 55, The arrow glyphs on line 55
(← before prev.title) and line 70 (→ after next.title) are hardcoded for LTR
languages and should be direction-aware for RTL locales like Arabic. Determine
if the current language (lang parameter) is RTL, then conditionally render the
appropriate arrow direction: for RTL locales, reverse the arrows so the previous
navigation shows → and next navigation shows ←, while keeping the current LTR
arrows for non-RTL languages. This ensures navigation cues visually align with
the reading direction of the locale.

<button
onClick={() => setDropdownOpen(!dropdownOpen)}
aria-expanded={dropdownOpen}
aria-haspopup="listbox"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix ARIA popup semantics for the language dropdown.

Line 107 sets aria-haspopup="listbox", but the popup renders navigation links (not listbox/options). This mismatch can confuse assistive tech. Use a menu pattern (menu/menuitem) or a true listbox pattern consistently.

Suggested fix
-            aria-haspopup="listbox"
+            aria-haspopup="menu"
+            aria-controls="language-menu"
@@
-              <div
+              <div
+                id="language-menu"
+                role="menu"
                 className="absolute right-0 rtl:left-0 rtl:right-auto z-20 mt-2 w-36 rounded-xl border p-1 shadow-lg transition-all bg-white border-[`#e2e8f0`] dark:bg-[`#0b0d12`] dark:border-[`#232a36`]"
               >
@@
-                    <Link
+                    <Link
+                      role="menuitem"

Also applies to: 123-123, 128-140

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/layout/Header.tsx` at line 107, The language dropdown
component in Header.tsx is using aria-haspopup="listbox" but the popup contains
navigation links instead of actual listbox options, creating a semantic mismatch
that confuses assistive technology. Change the aria-haspopup value from
"listbox" to "menu" to accurately reflect the menu pattern being rendered with
navigation links. Also apply this same ARIA semantic fix to all related
instances mentioned (around lines 123 and 128-140) to ensure consistent ARIA
patterns throughout the component. Verify that the overall component structure
(button trigger and popup content) follows the menu pattern semantics
consistently.

Comment thread src/i18n/dictionaries.ts Outdated
Comment thread src/lib/docs.ts
export type DocNavItem = {
slug: DocSlug;
title: Record<Locale, string>;
title: Record<string, string>;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Require en in DocNavItem.title while keeping locale flexibility.

Line 14 loosens the contract too much: Record<string, string> allows entries without "en", but downstream fallback relies on d.title["en"] always existing. Keep dynamic locale keys, but enforce English as required.

Suggested fix
+import type { Locale } from "`@/i18n/config`";
+
 export type DocNavItem = {
   slug: DocSlug;
-  title: Record<string, string>;
+  title: { en: string } & Partial<Record<Locale, string>>;
 };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/docs.ts` at line 14, The title field in the DocNavItem type
definition on line 14 is currently defined as Record<string, string>, which
allows any locale keys but does not guarantee that the "en" key exists. However,
downstream code relies on d.title["en"] always being present. Modify the title
field type to require the "en" key as mandatory while still allowing other
optional locale keys. This can be achieved by using an intersection type that
combines Record<string, string> with an object that explicitly requires the "en"
property.

Restores the project's original import pattern. Typed Record<Locale, Dictionary>
enforces at compile time that every configured locale has a dictionary, and stops
silently swallowing load errors / hiding missing translations.
@ecc-tools

ecc-tools Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR.

@DataDave-Dev
DataDave-Dev merged commit 2f605c2 into DataDave-Dev:main Jun 17, 2026
1 check passed
@coderabbitai coderabbitai Bot mentioned this pull request Jul 6, 2026
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants