The paragraph that skipped translation because it never asked
A reader caught it on a screenshot before I did: the Spanish footer had a translated tagline, a translated nav, a translated “Preferencias de análisis” link, and then, sitting right in the middle of all that, a full paragraph of English explaining how the site’s analytics work.
The i18n pass that shipped this site’s Spanish locale went through every string it could find in ui.ts, the shared strings object every component pulls from. It found the tagline. It found the nav labels. It found the “Analytics preferences” button label. It did not find the analytics description, because that paragraph was never in ui.ts at all. It was hardcoded directly into Footer.astro, three lines of English prose sitting right next to a {strings.footer.tagline} call that looked, at a glance, like it was doing the same job.
That’s the part worth remembering: a hardcoded string next to a translated one doesn’t look broken. It doesn’t throw a build error. It doesn’t fail a type check. It just quietly renders in the wrong language, forever, until someone reads the page in the locale it’s supposed to support and notices the seam.
The fix was mechanical once found: add footer.analyticsDescription to the shared strings interface, write the Spanish translation, swap the hardcoded paragraph for {strings.footer.analyticsDescription}. Three lines changed. The bug had been live since the Spanish locale shipped.
No process change coming out of this one. It’s a reminder that “translated” and “grep for hardcoded English strings across every component, not just the ones a checklist remembered to visit” aren’t the same audit.
Related reading
Translating a marketing page without duplicating it
The Spanish page existed, had a URL, showed up in hreflang - and every word was English. The fix that almost shipped was 130 duplicated lines waiting to drift.
Telling a Spanish reader why the page is in English
The fallback was the right default and completely silent. Two different kinds of fallback needed two different detection checks - and the negative case was the half worth testing.
The homepage was the one page i18n forgot
The language switcher worked perfectly. There was just nothing on the other side of it: six components of English literals, a flat English data file, and a dev server that lied for twenty minutes.