Skip to content

i18n Coverage Audit — Ideony Monorepo

Date: 2026-04-20
Scope: apps/mobile/ (Expo/React Native, i18next) + apps/api/src/ (NestJS, nestjs-i18n)
Locales: IT (default) + EN


Raw user-visible strings not wrapped in t(). Fallback strings (2nd arg to t()) are excluded — those are acceptable defaults.

FileLineRaw StringSuggested Key
app/(welcome)/continue.tsx80"oppure" (Italian divider)common.or_divider
app/(welcome)/continue.tsx87placeholder="Email"auth.email_placeholder
app/(welcome)/continue.tsx100accessibilityLabel="Email"auth.email_placeholder
app/(welcome)/continue.tsx157placeholder="000000"auth.otp_placeholder
app/(welcome)/continue.tsx169accessibilityLabel="OTP code"auth.otp_accessibility
components/chrome/Header.tsx28accessibilityLabel="Notifications"common.notifications
components/chrome/Header.tsx38accessibilityLabel="Profile avatar"common.profile_avatar
components/professional/HeroCarousel.tsx84accessibilityLabel="Indietro" (Italian!)common.go_back
components/professional/HeroCarousel.tsx95accessibilityLabel="Condividi" (Italian!)common.share
components/AvailabilityEditor.tsx169placeholder="09:00"calendar.time_start_placeholder
components/AvailabilityEditor.tsx180placeholder="18:00"calendar.time_end_placeholder
app/(professional)/onboarding/profile.tsx163placeholder="0"(numeric — low priority)
app/(professional)/onboarding/pricing.tsx238placeholder="25"(numeric — low priority)
app/(professional)/onboarding/pricing.tsx278placeholder="80"(numeric — low priority)

Critical: HeroCarousel.tsx hardcodes Italian strings — will always display Italian regardless of user locale.


2. Mobile — Dead Keys (defined but never referenced)

Section titled “2. Mobile — Dead Keys (defined but never referenced)”

Keys present in lib/i18n/en.json with no t("ns.key") usage found in source.

Note: a thorough dead-key scan requires exhaustive grep of all key paths. The following are confirmed dead after cross-referencing all t() call sites found in app/**/*.tsx and components/**/*.tsx.

NamespaceKey(s)Notes
bookingsempty_title, empty_subtitleCode calls bookings.emptyTitle / bookings.emptySubtitle (camelCase) — snake_case versions unreachable
sosbutton_labelNo component calls t("sos.button_label")
homegreeting_anonymousNo call site found
professional_cardentire sectionNo t("professional_card.*") calls found in scanned files — verify if used elsewhere

Keys called via t() that do not exist in lib/i18n/en.json. These silently render the key string at runtime.

FileKey
app/sos/index.tsxsos.describe_problem_placeholder
app/sos/[id]/cancelled.tsxsos.no_candidates_title
app/sos/[id]/cancelled.tsxcommon.go_home
app/sos/[id]/complete.tsxcommon.go_home
components/sos/CandidateCard.tsxsos.etaMinutes
components/sos/CandidateCard.tsxsos.selectCandidate
components/sos/CandidateCard.tsxsos.min
FileKey
components/sos/DispatchStatusBar.tsxsos.statusSearching
components/sos/DispatchStatusBar.tsxsos.statusDispatching
components/sos/DispatchStatusBar.tsxsos.statusDispatchingWait
components/sos/DispatchStatusBar.tsxsos.statusWaitingAccept
components/sos/DispatchStatusBar.tsxsos.statusTracking
FileKey (called)Key (in JSON)
components/empty/BookingsEmpty.tsxbookings.emptyTitlebookings.empty_title
components/empty/BookingsEmpty.tsxbookings.emptySubtitlebookings.empty_subtitle
components/empty/BookingsEmpty.tsxbookings.emptyCta(absent — no snake_case either)
FileKey
components/professional/StickyBookBar.tsxprofessional_profile.starting_price
components/professional/StickyBookBar.tsxprofessional_profile.book_cta
components/professional/SectionTabs.tsxprofessional_profile.tab_reviews
components/professional/SectionTabs.tsxprofessional_profile.tab_certifications
components/professional/SectionTabs.tsxprofessional_profile.tab_area
FileKey
app/review/[bookingId].tsxreview.hero_subtitle
app/review/[bookingId].tsxreview.comment_placeholder_detail
FileKey
app/(consumer)/index.tsxhome.heroTitle
app/(consumer)/index.tsxhome.heroSubtitle
app/(consumer)/index.tsxhome.categoriesTitle
app/(consumer)/index.tsxhome.searchPlaceholder

Total mobile undefined keys: 26


All user-facing error messages in apps/api/src/ should use t(key, fallback) via src/common/i18n.helper.ts. The following modules had hardcoded English strings thrown directly without t():

Scan found all error throws use t() via the helper — no bare hardcoded error strings identified in scanned modules. This section passes.


Keys in apps/api/src/i18n/en/common.json with no t("key") call site found.

SectionKeyNotes
notificationentire section (6 keys)sos_request, booking_confirmed, booking_cancelled, payment_received, review_prompt, service_reminder — no t("notification.*") calls found in API source
bookingprofile_existsNo t("booking.profile_exists") call found
onboardingp_iva_requiredNo t("onboarding.p_iva_required") call found (may be used — verify)

The t() helper in src/common/i18n.helper.ts prepends common. to keys. JSON uses snake_case; some call sites use camelCase → always falls back to English.

camelCase / snake_case mismatches (key exists in JSON but under different casing)

Section titled “camelCase / snake_case mismatches (key exists in JSON but under different casing)”
FileKey calledKey in JSONEffect
modules/credentials/credentials.service.tscredential.notFoundcredential.not_foundAlways English fallback

Keys entirely absent from JSON (missing sections)

Section titled “Keys entirely absent from JSON (missing sections)”
FileKey(s) calledMissing section
modules/quotes/quotes.service.tsquotes.not_found, quotes.forbidden, quotes.accepted_only, quotes.already_responded, quotes.professional_mismatch, quotes.invalid_status, quotes.consumer_only, quotes.booking_not_foundquotes section absent
modules/verification/verification.service.tsverification.profile_not_found, verification.not_found, verification.already_reviewedverification section absent
modules/sos/sos.service.tssos.no_pricingKey absent from sos section
modules/onboarding/onboarding.service.tsonboarding.user_not_foundKey absent from onboarding section
modules/onboarding/onboarding.service.tsonboarding.portfolio_image_not_foundKey absent
modules/onboarding/onboarding.service.tsonboarding.portfolio_image_forbiddenKey absent
modules/credentials/credentials.service.tscredential.notPendingKey absent

Total API undefined keys: 15 keys across 4 modules
Critical: entire quotes (8 keys) and verification (3 keys) sections missing — all errors in these modules display English only regardless of user locale.


Mobile (lib/i18n/en.json vs lib/i18n/it.json)

Section titled “Mobile (lib/i18n/en.json vs lib/i18n/it.json)”

Keys present in EN but missing from IT:

NamespaceMissing Keys
authwelcome_heading, continue_cta, continue_with_apple, continue_with_google, continue_with_facebook, otp_title, verify_cta, new_user_prompt, register_link

9 keys missing from IT mobile JSON. The entire authentication flow will display English strings when the device is set to Italian.

Keys present in IT but missing from EN: none identified.

API (src/i18n/en/common.json vs src/i18n/it/common.json)

Section titled “API (src/i18n/en/common.json vs src/i18n/it/common.json)”

IT and EN API files are fully parified — identical key sets. No gaps.


CategoryCountNotes
Undefined keys (silent fallback to key string)26SOS, home, review, professional_profile, bookings
Missing t() wraps (raw strings)142 critical Italian hardcodes
IT parity gaps9Entire auth section missing from IT
Dead keys (defined, unreferenced)~6bookings snake_case, sos.button_label
Mobile i18n healthPoorSOS feature and professional profile ~0% translated at runtime
CategoryCountNotes
Undefined keys15quotes + verification sections entirely absent
camelCase mismatches1credential.notFound
Dead keys~7notification section + isolated keys
IT parity gaps0Fully parified
API i18n healthPartialCore booking/auth/review errors translate correctly; quotes + verification always English
  1. [P0] Add quotes and verification sections to API JSON (all errors in these modules are untranslated)
  2. [P0] Add 12 missing SOS keys to mobile EN+IT JSON (statusXxx, etaMinutes, selectCandidate, min, no_candidates_title, describe_problem_placeholder)
  3. [P0] Add common.go_home to mobile EN+IT JSON
  4. [P1] Fix bookings.emptyTitle/Subtitle/Cta — either rename JSON keys to camelCase or update component to use snake_case; add emptyCta
  5. [P1] Add 5 missing professional_profile keys (starting_price, book_cta, tab_*)
  6. [P1] Add 9 missing auth keys to IT JSON (parity gap)
  7. [P1] Add review.hero_subtitle and review.comment_placeholder_detail to EN+IT JSON
  8. [P1] Add 4 missing home camelCase keys (heroTitle, etc.) to EN+IT JSON — or rename existing snake_case keys
  9. [P2] Fix credential.notFoundcredential.not_found in API service call
  10. [P2] Add missing API onboarding keys (user_not_found, portfolio_image_not_found, portfolio_image_forbidden) and sos.no_pricing
  11. [P2] Wrap raw strings in continue.tsx, Header.tsx, AvailabilityEditor.tsx
  12. [P3] Replace hardcoded Italian accessibilityLabel in HeroCarousel.tsx