<html lang="tr"> gibi tek bir nitelik, ekran okuyucunun sayfayı doğru aksanla mı yoksa robotik bir İngilizce telaffuzla mı okuyacağını belirler. Aynı nitelik tarayıcının sayfayı çevirmek için tek tıkla sunduğu “Türkçe'den çevir” uyarısını tetikler, kelimelerin nereden kesilebileceğini söyler ve arama motoruna sayfanın hangi dile yönelik olduğunu bildirir.
1. html-has-lang hatası nedir?
axe-core'un html-has-lang kuralı, kök <html> öğesinin lang niteliği taşımasını şart koşar. Buna ek olarak html-lang-valid kuralı, lang değerinin BCP 47 standardına uygun bir kod (örneğin tr, en, en-GB) olmasını ister.
Bu kurallar WCAG 2.1 3.1.1 Language of Page kriterinin doğrudan karşılığıdır ve A seviyesindedir. Yani uyumluluğun en alt eşiği bile <html lang>'e bağlıdır.
2. Neden önemli?
lang değerini birçok teknoloji aktif olarak kullanır:
- Ekran okuyucu telaffuzu: NVDA ve VoiceOver,
langdeğerine göre doğru ses motorunu seçer. Türkçe sayfadalang="en"kalmışsa “merhaba” kelimesi İngilizce ses motoruyla okunur ve anlaşılmaz hale gelir. - Tarayıcı çevirisi: Chrome ve Edge sayfa dilini
lang'dan algılar. Yanlış değer, gereksiz çeviri tekliflerine ya da çevirinin hiç önerilmemesine yol açar. - Yazım denetimi: Form alanlarındaki yazım denetleyicisi sayfanın diliyle çalışır. Yanlış lang, kullanıcının her doğru kelimesini yanlış olarak işaretletir.
- Tipografi: CSS'in
hyphens,quotesve tarihler/sayılarla ilgili davranışları lang'a duyarlıdır. - Arama motoru sınıflandırması: Google sayfanın hedef dilini
lang,hreflangve içerikten birlikte çıkarır. Tutarsızlık yanlış pazarda görünüm anlamına gelir.
Tek bir öznitelikte yapılacak hata; erişilebilirlik, UX ve SEO'yu birlikte etkiler.
3. Hangi durumlarda tetiklenir?
- lang niteliği yok:
<html>doğrudan açılmış ve niteliksiz bırakılmış. Eski şablonlarda en sık karşılaşılan hata. - Boş lang:
lang=""ya da yalnızca boşluk içeriyor. - Geçersiz dil kodu:
lang="tur"(BCP 47'detrolmalı),lang="turkce"ya da uydurulmuş kod. Bu durumdahtml-lang-validkuralı tetiklenir. - Yanlış dil kodu: Türkçe içerikli bir sayfada
lang="en". Kural geçer ama içerik kullanıcısı için ekran okuyucu tamamen kullanılamaz hale gelir. - xml:lang ile lang çelişiyor: XHTML uyumlu kalmak için iki nitelik birden tanımlanmış ama farklı değerler taşıyor.
html-xml-lang-mismatchkuralı bunu yakalar.
4. Doğru çözümler
4.1 Tek dilli sitede temel kullanım
<!DOCTYPE html>
<html>
<head>...</head>
<body>...</body>
</html><!DOCTYPE html>
<html lang="tr">
<head>...</head>
<body>...</body>
</html>4.2 Bölgesel varyantlar
BCP 47, ana dil koduna ülke veya bölge alt etiketini eklemenize izin verir: en-GB, en-US, pt-BR, zh-Hant. Bunu ne zaman yapmalı? Yalnızca yazım, telaffuz veya tarih biçimi gerçekten farklıysa. İngiltere İngilizcesi için en-GB yerleşik bir alışkanlıktır; Türkçenin bölgesel bir varyantını şu an için kullanmaya gerek yoktur, sadece tr yeterlidir.
<html lang="en-GB"> <!-- İngiliz İngilizcesi -->
<html lang="pt-BR"> <!-- Brezilya Portekizcesi -->
<html lang="zh-Hant"> <!-- Geleneksel Çince -->4.3 Çok dilli sitede dil değişimi
Site TR ve EN sürümleri sunuyorsa lang değerini her sürümde güncelleyin. Tek bir lang="en" hem Türkçe hem İngilizce sayfalarda bırakılırsa Türkçe sayfa için ekran okuyucu yanlış motoru kullanır.
// app/layout.tsx
import { cookies } from "next/headers";
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const c = await cookies();
const locale = c.get("locale")?.value === "tr" ? "tr" : "en";
return (
<html lang={locale}>
<body>{children}</body>
</html>
);
}4.4 Aynı sayfa içinde farklı dillerde içerik
Türkçe bir makalede İngilizce bir alıntı varsa, alıntıyı lang niteliğiyle işaretlemek ekran okuyucunun o paragrafa gelince motoru değiştirmesini sağlar.
<p>
Steve Jobs'un meşhur konuşmasında söylediği gibi:
<q lang="en">Stay hungry, stay foolish.</q>
</p>4.5 Dinamik dil değişimi (SPA)
SPA'da kullanıcı arayüzden dil değiştirdiğinde yalnızca içeriği değil, document.documentElement.lang'ı da güncelleyin.
function setLocale(locale: "tr" | "en") {
document.documentElement.lang = locale;
// Ekstra: sayfanın metin yönü için
document.documentElement.dir = locale === "ar" ? "rtl" : "ltr";
}5. Doğru dil kodu nasıl seçilir?
BCP 47 standardı, ISO 639 ve ISO 3166 kodlarını birleştirir. En yaygın kalıplar:
tr— Türkçeen— İngilizce (genel)en-US,en-GB,en-AU— bölgesel İngilizcelerde— Almancade-CH,de-AT— bölgesel Almancalarfr— Fransızcaar— Arapça (sağdan sola;dir="rtl"ile birlikte)zh-Hans,zh-Hant— Basitleştirilmiş / Geleneksel Çince
6. Gözden kaçan durumlar
- iframe'ler: İçeride yer alan dokümanın da kendi
<html lang>'i olmalıdır. Gömülü harita, video oynatıcı, ödeme iframe'i — hepsi ayrı doküman. - PDF'ler: İndirilebilir PDF'lerin de iç metadata'sında dil tanımı bulunmalıdır. WCAG bunu da kapsar.
- E-posta şablonları: Tarayıcıdan görüntülenen HTML e-postaların
lang'ı genellikle unutulur. Pek çok e-posta istemcisi ekran okuyucuda bu mailleri yanlış telaffuzla okur. - Çoklu dil tek
html'de: Bazı siteler tek HTML içerisinde iki dilde içerik gösterir. Bu durumda<html>'e ana dil yazılır, içerideki bloklara ayrılangverilir. - Yazılı çince/japonca/korece sayfa “en” bırakılmış: Tipografi, satır kesme ve fontlar ciddi biçimde bozulur. Mutlaka doğru kodla işaretleyin.
7. Nasıl test edilir?
- View Source: Sayfanın HTML kaynağına bakıp
<html lang="...">değerini kontrol etmek bir saniye sürer. - axe DevTools / Lighthouse: Eksik veya geçersiz lang'ı anında yakalar.
- Ekran okuyucu testi: NVDA veya VoiceOver açıkken sayfayı yükleyin. Türkçe içerik İngilizce telaffuzla okunuyorsa lang yanlış demektir.
- Keysonar SEO Tools: Site genelinde tüm sayfaların lang değerlerini listeler ve tutarsızlıkları öne çıkarır. Çok dilli sitelerde her sürümün doğru işaretlendiğinden emin olmak için.
8. Hızlı kontrol listesi
- Her sayfada <html> elementinde lang niteliği var.
- Lang değeri BCP 47 standardına uygun (tr, en, en-GB gibi).
- Lang değeri sayfanın gerçek içerik diliyle eşleşiyor.
- Çok dilli sitede her dil sürümü kendi lang değerini taşıyor.
- SPA'da dil değişiminde document.documentElement.lang güncelleniyor.
- Sayfa içindeki yabancı dil parçaları (alıntı, terim) kendi lang'ı ile işaretlendi.
- iframe içerikleri kendi <html lang>'lerine sahip.
- Sağdan sola yazılan dillerde dir='rtl' de lang ile birlikte ayarlanmış.
9. Referanslar
- WCAG 2.1 SC 3.1.1 — Language of Page — Level A
- WCAG 2.1 SC 3.1.2 — Language of Parts — Level AA
- BCP 47 — Tags for Identifying Languages
- HTML Living Standard — The lang attribute
- W3C: Choosing a Language Tag