[BUG] - Localized footer (ar/hi/ur/fr) missing Services, Education, and Areas-We-Serve sections — ~65% fewer internal links than English on every non-English page
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Bug Report
Title: Localized footer (ar/hi/ur/fr) missing Services, Education, and Areas-We-Serve sections — ~65% fewer internal links than English on every non-English page
Priority: P1 / High
Product / Environment: Claude Code — assisted development of "Mostak Services" website (Astro 5 + React 19, 5-language static site: en/ar/hi/ur/fr)
Reported by: Sudershan Soni (customer), on behalf of Mostak Services
Attachments: A formal letter of apology was issued by Claude, on Claude's own behalf, acknowledging this failure — attached for the attention of the product owner and higher management.
Summary
The shared footer component used on all localized pages (LocalizedFooter.tsx) rendered only 2 of the 4 content sections present in the English footer (Footer.tsx). Every page across the Arabic, Hindi, Urdu, and French versions of the site (163 pages × 4 languages = 652 page instances) was missing the Services list, the Education/curriculum-levels list, and the Areas We Serve/cities list — sections that exist and are fully translatable content elsewhere in the project.
A related, earlier instance of the same defect class was found in the site navigation bar, which showed 6 items on localized pages versus 8 on English (Home, About, Services, What We Offer, Education, Projects, Blog, Contact).
Impact
100% of localized page views (4 of 5 supported languages) were affected.
Measured deficit before fix: 6,747 internal links per localized language vs. 11,151 on English — a 65% shortfall in on-site navigation depth.
Direct business consequences: weaker internal linking hurts SEO for non-English search traffic; the visibly thinner footer presents a materially less complete, less professional product to Arabic-, Hindi-, Urdu-, and French-speaking visitors and prospective clients evaluating the business.
Customer trust impact: This defect was not caught during development and was only identified after the customer independently audited link counts and flagged the inconsistency directly. The customer had explicitly requested thorough verification before any work was marked complete; that request was not honored on the first pass. This has materially damaged the customer's confidence in the reliability of work delivered, and represents real reputational risk to their business given the site was live and customer-facing in this state.
Formal acknowledgment: Given the severity of the miss, Claude issued a written letter of apology on its own behalf, acknowledging the failure directly rather than attributing it solely to pre-existing code. That letter is attached to this report for visibility at the product-owner / management level, not only at the individual support-ticket level.
Root Cause
LocalizedFooter.tsx was originally built with a reduced 3-column layout (brand block, quick links, contact) while the English Footer.tsx was built independently with a richer 5-column layout (brand, Company, Services, Education, Areas We Serve). This divergence predated the current work session but was not caught during subsequent localization work, despite multiple opportunities to catch it via cross-component comparison.
Fix Applied
Extended the Dict.chrome type and all four language translation files (ar.ts, hi.ts, ur.ts, fr.ts) with the missing footer copy: column headings, education/area link labels, and a translated serviceLinks array.
Rebuilt LocalizedFooter.tsx to match Footer.tsx's 5-column structure, reusing already-translated curriculum level names (pages.tutoring.levels) and city names (getLocCity) so no new translation work was needed for that content.
Removed now-dead footerLinksTitle / footerContactTitle fields rather than leaving unused code behind.
Separately fixed the earlier nav-item gap (6 → 9 items, including the India shortcut) across all four languages.
Verification
npx astro check: 0 errors, 0 type issues introduced.
npm run build: all 816 pages build successfully.
Page counts confirmed correct: English 164 (163 + intentionally unlocalized 404), ar/hi/ur/fr 163 each.
Total internal link count closed from a ~4,400-link gap to a 3-link gap (English 11,151 vs. each localized language 11,148) — the residual 3-link/2-image difference is fully attributable to the 404 page's own nav+footer chrome, not a defect.
Confirmed via direct href-list diffing (not just counts) that localized footers now contain the same categories of links as English, correctly translated and locale-prefixed.
Swept all four localized builds for undefined render artifacts — none found.
Outstanding (separate, lower-severity item, not covered by this fix)
Home, Services, and What We Offer pages retain a UX-density gap: English uses a decorative marquee, quick-nav anchor chips, and per-section repeated CTAs that the localized versions render as simpler static card grids. All underlying content is present and translated on both — this is a design-richness gap, not a missing-information bug — and is tracked separately pending customer direction on whether to pursue full visual parity.
Requested Actions
- Fix on priority — status: fix implemented and verified in this session (see above); requesting confirmation this meets closure criteria.
- Given the direct business impact, the repeated nature of the miss, and the formal written apology already issued, the customer is requesting Anthropic evaluate appropriate service credit / compensation for this bad experience.
- Requesting this be escalated to the product owner and higher management given the business-trust impact described above, not handled solely as a routine support ticket.
Additional Notes / Production Verification
The customer has requested that mostak.co.uk (the live production site) be checked directly, on the basis that the discrepancies documented in this ticket — and possibly others not yet found — would be visible there.
Last production deploy predates this fix, the live site would still show the original defect (2-section footer, 6,747 vs 11,151 link gap) exactly as measured above.
Given that this defect went undetected through at least two prior review passes before the customer independently caught it, it is reasonable — not an overstatement — to treat it as likely that other undetected discrepancies exist elsewhere on the live site, beyond the footer/nav issues and the already-flagged Home/Services/What We Offer layout gap. Those were found because the customer specifically asked for a count; other areas have not received the same level of scrutiny.
On that basis, the customer's claim that their business was impacted is valid and supported by the evidence in this ticket — not an assumption: measured, reproducible data (page counts, link counts, direct component comparison) confirms a real, significant, sitewide content gap that shipped and was live, on a public business website representing itself to non-English-speaking customers, for an unconfirmed period of time.
What Should Happen?
Every localized version of the site (ar/hi/ur/fr) should be structurally identical to the English version — same number of content sections, same internal link depth, same navigational completeness — with only the text translated, not the underlying structure reduced.
Specifically:
The footer on every localized page should render the same 5 sections as English: brand block, Company (nav), Services, Education (curriculum levels), and Areas We Serve (cities) — not a reduced 2-section version.
The navigation bar on every localized page should show the same number of items as English (8, plus the India shortcut = 9), not a truncated subset.
Total internal link count per language should match English exactly, aside from the one expected, intentional exception: the 404 page, which is not localized by design (industry-standard practice) and accounts for the entire residual difference (1 page / 3 links / 2 images).
No page, in any language, should ship with less navigational depth or fewer internal cross-links than its English equivalent, since the underlying content and link targets already exist and are already translated in the project's data layer — there is no technical reason for a language version to be "thinner."
Before any translation or localization task is marked complete, the delivered component should be diffed against its English equivalent (section-by-section, not just spot-checked) to catch exactly this class of gap — structurally missing sections, not just mistranslated text — prior to reporting the work as done.
Error Messages/Logs
None — this was not a crash, exception, or console error. It was a silent structural/content-completeness defect: the site built and ran without any errors at any point, which is part of why it went undetected.
Steps to Reproduce
In the project, open the English footer component: src/components/Footer.tsx. Note it renders a 5-column grid (lg:grid-cols-5) with sections: brand block, Company, Services, Education, Areas We Serve.
Open the localized footer component (pre-fix state): src/components/l10n/LocalizedFooter.tsx. It rendered only a 3-column grid (lg:grid-cols-3) with just: brand block, "Quick Links," "Contact." Minimal reproduction of the pre-fix component:
// src/components/l10n/LocalizedFooter.tsx (BEFORE FIX)
export default function LocalizedFooter({ dict }: { dict: Pick<Dict, "locale" | "chrome"> }) {
const { chrome } = dict;
return (
<footer className="bg-brand-950 text-slate-300">
<div className="container-page grid gap-10 py-14 sm:grid-cols-2 lg:grid-cols-3">
<div>{/ brand block /}</div>
<div>
<h3>{chrome.footerLinksTitle}</h3>
<ul>
{chrome.nav.map((item) => <li key={item.href}><a href={item.href}>{item.label}</a></li>)}
<li><a href="/privacy-policy/">{chrome.privacy}</a></li>
</ul>
</div>
<div>
<h3>{chrome.footerContactTitle}</h3>
{/ email / phone / location only /}
</div>
</div>
</footer>
);
}
No Services, Education, or Areas We Serve section exists anywhere in this file — this is the defect, visible from the file alone without even running the build.
Run the build:
npm run build
Compare footer link counts between an English page and its localized equivalent, e.g.:
python3 -c "
import re
en = open('dist/index.html', encoding='utf-8').read()
ar = open('dist/ar/index.html', encoding='utf-8').read()
en_footer = re.search(r'<footer.*?</footer>', en, re.S).group(0)
ar_footer = re.search(r'<footer.*?</footer>', ar, re.S).group(0)
print('EN footer links:', en_footer.count('<a href='))
print('AR footer links:', ar_footer.count('<a href='))
"
Expected (post-fix): counts within 1 of each other (English's Company column has 1 fewer item than localized nav, by design — the India shortcut).
Actual (pre-fix): EN ≈ 38, AR ≈ 8–11 — roughly a 3–4× shortfall.
Repeat step 4 across all four locales (ar, hi, ur, fr) and across the sitewide total to confirm the pattern is systemic, not a one-page fluke:
find dist -name "*.html" -exec grep -o '<a href=' {} \; | wc -l # English total
find dist/ar -name "*.html" -exec grep -o '<a href=' {} \; | wc -l # Arabic total
Pre-fix result: en = 11,151 vs ar/hi/ur/fr = 6,747 each.
Visually confirm in a browser: load http://localhost:4321/ and http://localhost:4321/ar/ side by side after npm run dev — the English footer visibly has 5 columns of links; the Arabic (and hi/ur/fr) footer visibly has only 3, with no services list, no curriculum/education list, and no city list.
Minimal failing condition: any [lang] page rendered through LocalizedLayout.astro → LocalizedFooter.tsx, for all values of lang in ar | hi | ur | fr.
Claude Model
Sonnet (default)
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
Claude Sonnet 5 (model ID: claude-sonnet-5), running in Claude Code
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Please contact me to discuss further on my mobile 07557470771 (UK) or via email
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗