i18n(web): full landing page TR↔EN — language switcher actually works now
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled

Root cause: landing was almost entirely hard-coded Turkish (5 t() calls in
1889 lines), and initLocale() — which reads the persisted locale from
localStorage on boot — was never called from main.tsx, so a reload always
reverted to the TR default.

This commit fixes both.

apps/web/src/main.tsx
- Call initLocale() before first render so the persisted choice survives reload.

apps/web/src/routes/__root.tsx
- Translate the skip-to-content link via a new `a11y.skipToContent` key.

apps/web/src/routes/index.tsx
- Internationalize ~145 user-visible strings across hero, brand strip, features,
  comparison table, bento grid, use cases, stats, dashboard showcase, ecommerce
  block, testimonials, pricing tiers, FAQ, final CTA, referral banner and ARIA
  labels. Module-scope data arrays moved inside the component so re-renders
  pick up the active locale.
- Wrap the three Remotion players (Schema / Dashboard / Ecommerce) so they read
  the current locale and pass translated labels into their inputProps.

Remotion demos (DashboardDemo, EcommerceDemo, SchemaDemo)
- Each now accepts a `labels` prop (DashboardDemoLabels / EcommerceDemoLabels /
  partLabel). All hard-coded TR sidebar items, placeholders, category names,
  product names, "Add to Cart" buttons, the cart-added toast, overlays and
  stat labels are now driven by labels with a TR fallback (keeps Remotion
  Studio preview working standalone).

messages/{tr,en}.json
- New blocks: `a11y`, `landing.*` (huge tree covering every section above),
  `landing.dashboardDemo`, `landing.ecommerceDemo`.

Intentionally preserved as data, not translated: brand names (Volkswagen,
Mitsubishi …), VIN literals, OEM codes (1J0 820 803F …), numeric stat values
(1.2sn, 27, 1M+, %99.9 …), prices (200/350/500/999), and the testimonial
person name "Özge D." (proper noun).

Verified: typecheck clean, 17/17 test files / 57/57 tests pass, biome clean,
Playwright TR↔EN round-trip succeeds, only the testimonial name remains as
Turkish on the EN page.
This commit is contained in:
2026-05-31 23:50:52 +03:00
parent 931c0cfd85
commit 229666e333
8 changed files with 1427 additions and 557 deletions

View File

@@ -31,6 +31,9 @@
"register": "Kayıt Ol",
"reload": "Sayfayı yenile"
},
"a11y": {
"skipToContent": "İçeriğe atla"
},
"nav": {
"dashboard": "Gösterge Paneli",
"search": "Arama",
@@ -657,5 +660,411 @@
"partsHeading": "Parçalar (OEM)",
"noPartMatch": "Eşleşen parça yok. (Yalnızca açılmış kategorilerin parçaları aranır.)",
"partsCount": "{count} parça"
},
"landing": {
"meta": {
"title": "Şase Numarası Sorgulama & OEM Parça Kataloğu | Sase.tr",
"description": "Araç şase numarasını (VIN) girin, saniyeler içinde OEM parça kodlarına ulaşın. 27 marka, 1M+ parça. Yanlış sipariş yapmadan doğru parçayı bulun.",
"schemaOrgDescription": "Türkiye'nin VIN/şase numarası sorgulama ve OEM yedek parça kataloğu platformu.",
"schemaSoftwareDescription": "Araç şase numarası ile OEM yedek parça sorgulama platformu."
},
"nav": {
"features": "Özellikler",
"howItWorks": "Nasıl Çalışır",
"pricing": "Fiyatlar",
"blog": "Blog",
"contact": "İletişim",
"login": "Giriş Yap",
"register": "30 Gün Ücretsiz Deneyin",
"dashboard": "Panele Git"
},
"aria": {
"themeToggle": "Tema değiştir",
"showBrand": "{brand} markasını göster"
},
"hero": {
"lossPill": "Her yanlış parça siparişi 200-500 TL'ye mal olur",
"ratingLabel": "4.9/5",
"socialProofLabel": "500+ İşletme Güveniyor",
"title": "Doğru Parçayı Anında Bulun",
"subtitle": "Birden fazla katalogda çapraz sorgulama ile her zaman en güncel OEM kodları. Şase numarasını girin, doğru parçayı ilk seferde gönderin.",
"vinPlaceholder": "Örnek: WVWZZZ1JZ3W597935",
"searchCta": "Ara",
"decoding": "Çözülüyor...",
"loadingVehicle": "Araç bilgileri alınıyor...",
"ctaOpenCatalog": "Parça kataloğunu aç",
"ctaAccessFullCatalog": "Tam parça kataloğuna eriş",
"vinNotFound": "Şase bilgisi bulunamadı. Lütfen kontrol edip tekrar deneyin.",
"noVinPrompt": "Şase numaranız yok mu?",
"tryExample": "Örnek aramayı deneyin →",
"metricSpeed": "Ortalama 1.2sn Sonuç",
"metricBrands": "27 Marka Desteği",
"metricParts": "1M+ OEM Parça"
},
"brandStrip": {
"supported": "Desteklenen 27 Otomobil Markası"
},
"testimonialStrip": {
"title": "Kullanıcılarımız ne diyor?",
"items": {
"0": {
"text": "Sase.tr ile yanlış parça siparişlerimiz %80 azaldı. Artık gönül rahatlığıyla sipariş veriyoruz.",
"name": "Ahmet Y.",
"role": "Yedek Parça Mağazası"
},
"1": {
"text": "Ayda 40 saatten fazla zaman kazanıyoruz. Şase numarasını girip anında doğru koda ulaşmak inanılmaz.",
"name": "Mehmet K.",
"role": "Oto Servis İşletmecisi"
},
"2": {
"text": "Online mağazamıza entegre ettik, iade oranımız yarıya düştü. Müşteri memnuniyeti gözle görülür arttı.",
"name": "Özge D.",
"role": "E-Ticaret Yöneticisi"
}
}
},
"features": {
"badge": "Çözümlerimiz",
"title": "Şase Çözme & Parça Kataloğu",
"subtitle": "Araç tanımlamadan parça siparişine kadar tüm süreç tek platformda.",
"loading": "Yükleniyor…",
"ctaTry": "Hemen Deneyin",
"vin": {
"title": "Şase Çözme",
"description": "Müşteri araç bilgisini tam bilmiyor mu? Şase numarasını girin — marka, model, motor, donanım saniyeler içinde karşınızda.",
"bullet1": "Marka, model ve yıl tespiti",
"bullet2": "Motor ve şanzıman detayları",
"bullet3": "Donanım paketi bilgileri",
"mockupTitle": "Şase Çözme — Araç Bilgileri",
"labelMake": "Marka",
"labelModel": "Model",
"labelYear": "Yıl",
"labelEngine": "Motor",
"labelBody": "Kasa",
"valueBody": "Hatchback"
},
"schema": {
"title": "İnteraktif Şema",
"description": "Parça kataloglarında kaybolmak yerine, tıklanabilir diyagramlarda parçayı görsel olarak bulun.",
"bullet1": "Tıklanabilir parça diyagramları",
"bullet2": "Zoom & pan navigasyon",
"bullet3": "Alt kategori derinliği",
"mockupTitle": "İnteraktif Şema — Motor Bölgesi"
},
"oem": {
"title": "OEM Parça Numaraları",
"description": "Birden fazla katalogda çapraz sorgulama yaparak her zaman en güncel ve doğru OEM kodlarını sunar — yanlış parça, iade derdi tarih olur.",
"bullet1": "Çoklu katalog çapraz sorgulama",
"bullet2": "Her zaman güncel OEM kodları",
"bullet3": "Fiyat karşılaştırma",
"mockupTitle": "OEM Katalog — Parça Listesi",
"part1": "Klima Kompresörü",
"part2": "Kalorifer Motoru",
"part3": "Ön Fren Balatası"
}
},
"compare": {
"badge": "Karşılaştırma",
"title": "Manuel Yöntem vs Sase.tr",
"manualHeader": "Manuel",
"saseHeader": "Sase.tr",
"rows": {
"0": {
"label": "Parça arama süresi",
"manual": "~15 dakika",
"sase": "30 saniye"
},
"1": {
"label": "Yanlış parça riski",
"manual": "Yüksek",
"sase": "Sıfıra yakın"
},
"2": {
"label": "OEM kodu bulma",
"manual": "Tek katalog, güncel olmayabilir",
"sase": "Çoklu katalog çapraz sorgu"
},
"3": {
"label": "Fiyat karşılaştırma",
"manual": "İmkansız",
"sase": "Tek ekranda"
},
"4": {
"label": "Aylık zaman tasarrufu",
"manual": "—",
"sase": "~40 saat"
}
}
},
"howItWorks": {
"badge": "Nasıl Çalışır",
"title": "3 Adımda Orijinal Parçaya Ulaşın",
"items": {
"0": {
"title": "Şase Girin",
"description": "17 haneli şase numarasını girin, araç anında tanımlansın."
},
"1": {
"title": "27 Marka",
"description": "Avrupa, Asya ve Amerikan markaları tek çatı altında."
},
"2": {
"title": "Kategorileri Seçin",
"description": "Motor, şasi, elektrik... İstediğiniz parça kategorisine dalın."
},
"3": {
"title": "Şema İnceleyin",
"description": "İnteraktif teknik diyagramlarda parça konumlarını görsel olarak keşfedin."
},
"4": {
"title": "OEM Kod Alın",
"description": "Orijinal üretici parça numarasını kopyalayın, siparişe hazır olun."
},
"5": {
"title": "Sipariş Verin",
"description": "Doğru parça numarasıyla tedarikçilere hızlıca sipariş oluşturun."
}
}
},
"useCases": {
"badge": "Kullanım Alanları",
"title": "Kimler İçin?",
"items": {
"0": {
"title": "Yedek Parça Arama",
"description": "Şase numarası ile araç modelinize uygun orijinal parçaları anında bulun."
},
"1": {
"title": "Orijinal Parça Numarası",
"description": "OEM parça kodlarına erişerek doğru parçayı ilk seferde sipariş edin."
},
"2": {
"title": "Araç Tanımlama",
"description": "Şase çözme ile aracın tüm teknik detaylarını ve donanım bilgilerini öğrenin."
},
"3": {
"title": "Çıkma Parça Doğrulama",
"description": "OEM kodlarıyla çıkma parçaların orijinalliğini ve uyumluluğunu kontrol edin."
},
"4": {
"title": "Servis & Bakım",
"description": "Bakım planlarına uygun parça listeleriyle servis süreçlerini hızlandırın."
}
},
"ctaCard": {
"title": "Farklı bir ihtiyacınız mı var?",
"description": "Özel entegrasyon veya toplu sorgulama ihtiyacınız varsa bize ulaşın.",
"cta": "Bize Ulaşın"
}
},
"stats": {
"badge": "Platform",
"titleLine1": "Rakamlarla",
"titleLine2": "Sase.tr",
"items": {
"0": { "value": "1.2sn", "label": "Ortalama sorgu süresi" },
"1": { "value": "27", "label": "Desteklenen marka" },
"2": { "value": "1M+", "label": "OEM parça numarası" },
"3": { "value": "%99.9", "label": "Platform erişilebilirlik" }
}
},
"dashboard": {
"title": "Tüm Veriler, Tek Platform",
"subtitle": "Şase çözme, parça kataloğu ve interaktif şemalar tek bir arayüzde.",
"frameTitle": "sase.tr/dashboard",
"loading": "Yükleniyor…",
"floatVin": "Şase Arama",
"floatSchema": "İnteraktif Şema",
"floatOem": "OEM Kodları"
},
"dashboardDemo": {
"sidebar": {
"dashboard": "Dashboard",
"vinSearch": "Şase Arama",
"catalog": "Katalog",
"diagrams": "Şemalar",
"settings": "Ayarlar"
},
"categories": {
"engine": "Motor",
"chassis": "Şasi",
"electrical": "Elektrik",
"body": "Karoseri",
"brakes": "Fren"
},
"parts": {
"acCompressor": "Klima Kompresörü",
"brakePads": "Fren Balatası",
"heaterBlower": "Kalorifer Motoru"
},
"vinPlaceholder": "Şase numarası girin...",
"categorySelectTitle": "Kategori Seçin",
"schemaViewTitle": "Motor — Şema Görünümü",
"oemListTitle": "OEM Parça Listesi"
},
"ecommerceDemo": {
"products": {
"brakePads": "Fren Balatası",
"acCompressor": "Klima Kompresörü",
"shockAbsorber": "Amortisör",
"oilFilter": "Yağ Filtresi",
"wiperMotor": "Silecek Motoru",
"headlight": "Ön Far"
},
"searchPlaceholder": "Parça ara...",
"preReturnBadge": "%23 iade oranı",
"addToCart": "Sepete Ekle",
"cartAddedToast": "Fren Balatası sepete eklendi",
"conversionOverlay": "Dönüşüm: %94",
"statReturnRate": "İade oranı",
"statConversionRate": "Dönüşüm oranı",
"statSatisfaction": "Müşteri memnuniyeti"
},
"ecommerce": {
"badge": "E-Ticaret Entegrasyonu",
"title": "Kendi Sitenize Şase Çözme Gücü Katın",
"subtitle": "Müşterileriniz yanlış parça sipariş edip iade mi açıyor? Sase.tr entegrasyonu ile VIN bazlı filtreleme ekleyin — iadeler düşsün, dönüşüm artsın.",
"frameTitle": "otoyedekparca.co — Sase.tr Entegrasyonu",
"loading": "Yükleniyor…",
"easyBadge": "Kolay Entegrasyon",
"cardTitle": "Birkaç Satır Kod, Büyük Fark",
"cardBody": "E-ticaret sitenize Sase.tr'nin VIN çözme motorunu entegre edin. Müşterileriniz şase numarasını girsin — sadece araçlarına uygun parçalar listelensin.",
"bullet1": "API & Widget — Birkaç satır kodla sitenize entegre edin",
"bullet2": "VIN Bazlı Filtreleme — Sadece uyumlu parçalar görünsün",
"bullet3": "İade Oranını Düşürün — Doğru parça, ilk seferde",
"bullet4": "White-Label — Widget sitenizin tasarımına uyum sağlar",
"cta": "İletişime Geçin",
"stats": {
"0": { "value": "%42", "label": "Daha Az İade" },
"1": { "value": "%35", "label": "Daha Yüksek Dönüşüm" },
"2": { "value": "<30dk", "label": "Entegrasyon Süresi" }
}
},
"testimonials": {
"badge": "Müşteri Yorumları",
"title": "İşletme Sahipleri Ne Diyor?",
"items": {
"0": {
"name": "Ahmet Y.",
"role": "Yedek Parça Mağazası Sahibi",
"text": "Eskiden bir parça aramak için 3-4 katalog açıyordum. Sase.tr ile şase numarasını giriyorum, 30 saniyede doğru OEM kodunu buluyorum. İade oranımız %80 düştü."
},
"1": {
"name": "Mehmet K.",
"role": "Oto Servis İşletmecisi",
"text": "Sase.tr'ye geçtiğimizden beri yanlış parça siparişlerimiz neredeyse sıfıra indi. Aylık 40 saatin üzerinde zaman tasarrufu sağlıyoruz."
},
"2": {
"name": "Özge D.",
"role": "E-Ticaret Yöneticisi",
"text": "Online mağazamıza VIN entegrasyonu ekledik. Müşteriler şase numarasını giriyor, sadece uyumlu parçalar listeleniyor. İade oranımız %42 düştü."
},
"3": {
"name": "Burak T.",
"role": "Filo Yöneticisi",
"text": "200+ araçlık filomuz için parça yönetimi çok kolay hale geldi. Özellikle interaktif şema özelliği montaj sürecini çok hızlandırıyor."
}
}
},
"pricing": {
"badge": "Fiyatlandırma",
"titleLine1": "Günde 7 TL'den",
"titleLine2": "başlayan fiyatlar.",
"subtitle": "Tek bir yanlış parça iadesinin maliyetinden daha az. Tüm planlarda 30 gün ücretsiz deneme var, kart bilgisi gerekmez.",
"perMonth": "/ay",
"currency": "TL",
"yearlyPrice": "yıllık {amount} TL",
"tryFree": "30 gün ücretsiz dene",
"plans": {
"brand1": {
"name": "1 Marka",
"description": "Tek marka için erişim",
"feature1": "1 marka seçimi",
"feature2": "Sınırsız VIN arama",
"feature3": "Parça kataloğu",
"feature4": "Şema görüntüleyici"
},
"brand2": {
"name": "2 Marka",
"description": "İki farklı marka",
"feature1": "2 marka seçimi",
"feature2": "Sınırsız VIN arama",
"feature3": "Parça kataloğu",
"feature4": "Öncelikli destek"
},
"brand3": {
"name": "3 Marka",
"description": "Üç marka kapsamlı",
"feature1": "3 marka seçimi",
"feature2": "Sınırsız VIN arama",
"feature3": "Parça kataloğu",
"feature4": "Öncelikli destek"
}
},
"full": {
"badge": "En çok tercih edilen",
"name": "Full Paket",
"description": "Tüm markalara sınırsız erişim. Tek bir aboneliğe sığdırdık.",
"priceUnit": "TL/ay",
"yearlyNote": "yıllık 9.990 TL — ayda 832 TL'ye denk gelir",
"ctaTry": "30 gün ücretsiz dene",
"ctaFineprint": "Kart bilgisi gerekmez. İstediğin zaman iptal et.",
"included": "Pakete dahil",
"feature1": "Tüm 27 markaya erişim",
"feature2": "Sınırsız VIN arama",
"feature3": "OEM parça kataloğu",
"feature4": "İnteraktif şema görüntüleyici",
"feature5": "Geçmiş sorgular & favoriler",
"feature6": "Öncelikli e-posta desteği",
"feature7": "API erişimi (talep üzerine)",
"feature8": "Toplu sorgu özelliği"
},
"detailedComparison": "Detaylı karşılaştırmayı gör"
},
"faq": {
"badge": "SSS",
"title": "Sık Sorulan Sorular",
"items": {
"0": {
"q": "Hangi markaları destekliyorsunuz?",
"a": "Şu an 27 otomobil markası destekleniyor ve liste sürekli genişliyor. Şase numaranızı arama kutusuna girerek aracınızın desteklenip desteklenmediğini hemen görebilirsiniz."
},
"1": {
"q": "Verilerim güvende mi?",
"a": "Tüm trafik SSL ile şifrelenir ve verileriniz KVKK'ya uygun şekilde işlenir. Sorgu geçmişiniz yalnızca size özeldir."
},
"2": {
"q": "Kart bilgisi gerekiyor mu?",
"a": "Hayır. 30 günlük ücretsiz deneme için kredi kartı bilgisi istemiyoruz; dilediğiniz an vazgeçebilirsiniz."
},
"3": {
"q": "İstediğim zaman iptal edebilir miyim?",
"a": "Evet, taahhüt yok. Aboneliğinizi panelden tek tıkla iptal edebilirsiniz."
},
"4": {
"q": "Mevcut e-ticaret veya servis sistemime entegre olur mu?",
"a": "Full Paket'te API erişimi ve toplu sorgu ile sistemlerinize entegre edebilirsiniz (talep üzerine kurulum desteği)."
},
"5": {
"q": "Şase numarasını bilmiyorsam ne olur?",
"a": "Marka ve model üzerinden de katalogda gezebilir, ya da ana sayfadaki örnek aramayı deneyerek platformu test edebilirsiniz."
}
}
},
"finalCta": {
"title": "Her Yanlış Parça Size 200-500 TL'ye Mal Oluyor",
"subtitle": "İade kargosu, müşteri kaybı, zaman kaybı. Şase çözme ile ilk seferde doğru parçayı bulun.",
"cta": "30 Gün Ücretsiz Başla — Kart Gerekmez",
"trust": "KVKK uyumlu · SSL şifreli · Kart bilgisi gerekmez"
},
"referral": {
"title": "Arkadaşını Davet Et",
"description": "3 davet = +7 gün ücretsiz, 5 davet = +1 ay ücretsiz",
"cta": "Davet Kodunuzu Alın"
},
"errors": {
"decodeGeneric": "Bir hata oluştu. Lütfen tekrar deneyin."
}
}
}