Detailed guide

Language Declaration Guide

View contents

Complete Technical Guide to Language Declaration: BCP 47, WCAG, and International SEO

Introduction

If you’re already familiar with language declaration fundamentals from our introductory guide, this advanced technical guide will equip you with deep knowledge of BCP 47, complete WCAG compliance, and implementation strategies for complex multilingual sites.

Correct language declaration isn’t just an HTML tag—it’s the foundation of international accessibility, effective multilingual SEO, and user experience for global audiences.

BCP 47 Anatomy: The Standard Behind lang

What is BCP 47?

BCP 47 (Best Current Practice 47) is the IETF standard that defines the structure of language tags¹. It’s the format used by HTML’s lang attribute and is much more than two-letter codes.

Complete Structure of a BCP 47 Tag

language-extlang-script-region-variant-extension-privateuse
Component Example Description
language en ISO 639-1 code (required)
extlang cmn (Mandarin) Sub-language (rare)
script Latn, Hans Writing system
region US, GB, 419 Country or region
variant valencia Dialect variant
extension u-nu-thai Unicode extensions
privateuse x-custom Private use

Practical BCP 47 Examples

<!-- Generic English -->
<html lang="en">

<!-- English (United States) -->
<html lang="en-US">

<!-- English (United Kingdom) -->
<html lang="en-GB">

<!-- English (Australia) -->
<html lang="en-AU">

<!-- Simplified Chinese (Mainland China) -->
<html lang="zh-Hans-CN">

<!-- Traditional Chinese (Taiwan) -->
<html lang="zh-Hant-TW">

<!-- Brazilian Portuguese -->
<html lang="pt-BR">

<!-- Serbian in Cyrillic script -->
<html lang="sr-Cyrl">

<!-- Serbian in Latin script -->
<html lang="sr-Latn">

<!-- Azerbaijani in Arabic script -->
<html lang="az-Arab">

<!-- Spanish (Latin America - region code 419) -->
<html lang="es-419">

<!-- English with Unicode extension for Thai numerals -->
<html lang="en-u-nu-thai">

When to Use Each Specificity Level

Language Only (en, es, fr)

Use when:

  • Content is understandable to all speakers of the language
  • No significant regional differences
  • You want maximum compatibility
<!-- Technical article about programming - universal -->
<html lang="en">

Language + Region (en-US, en-GB, pt-BR)

Use when:

  • Content has region-specific vocabulary
  • Important spelling differences (color vs colour)
  • Geographic targeting for SEO
  • Country-specific legal or regulatory content
<!-- Online store with USD prices -->
<html lang="en-US">

<!-- Legal documentation for UK -->
<html lang="en-GB">

Language + Script (zh-Hans, sr-Cyrl)

Use when:

  • The language uses multiple writing systems
  • You want to specify the script without binding to a region
<!-- Simplified Chinese (without specifying country) -->
<html lang="zh-Hans">

WCAG 2.2 Compliance: Complete Requirements

Criterion 3.1.1: Language of Page (Level A)²

Requirement: The default human language of each Web page can be programmatically determined.

Sufficient techniques:

<!-- H57: Using the lang attribute on the html element -->
<!DOCTYPE html>
<html lang="en">
<head>
  <title>My Website</title>
</head>
<body>
  <!-- All content in English -->
</body>
</html>

Common errors causing non-compliance:

  1. Missing lang attribute entirely:
<!-- ❌ FAILS WCAG 3.1.1 -->
<html>
  1. Invalid language code:
<!-- ❌ FAILS WCAG 3.1.1 - "english" is not a valid code -->
<html lang="english">
  1. Wrong language for content:
<!-- ❌ FAILS WCAG 3.1.1 - Spanish content, declared as English -->
<html lang="en">
<body>
  <h1>Bienvenido a nuestro sitio</h1>
</body>
</html>

Criterion 3.1.2: Language of Parts (Level AA)³

Requirement: The human language of each passage or phrase in the content can be programmatically determined except for proper names, technical terms, words of indeterminate language, and words or phrases that have become part of the vernacular of the immediately surrounding text.

Sufficient techniques:

<html lang="en">
<body>
  <p>This article is about web development.</p>

  <!-- Spanish quote - REQUIRES lang -->
  <blockquote lang="es">
    <p>"El mejor código es el que no existe."</p>
    <cite>— Anonymous Spanish Developer</cite>
  </blockquote>

  <p>As the quote above states, simplicity is key.</p>

  <!-- Technical term in code - DOES NOT require lang (technical term) -->
  <p>We use <code>localStorage</code> for data storage.</p>

  <!-- Proper noun - DOES NOT require lang -->
  <p>The company Google was founded in 1998.</p>

  <!-- Foreign word adopted into English - DOES NOT require lang -->
  <p>The software has a user-friendly interface.</p>
</body>
</html>

When to declare language on sections:

Content Requires lang? Reason
Textual quotes ✅ Yes Significant content in another language
Poems/lyrics ✅ Yes Creative content in original language
Testimonials ✅ Yes User’s voice in their language
Source code ⚠️ Optional Generally lang="en"
Technical terms ❌ No Explicit WCAG exception
Proper nouns ❌ No Explicit WCAG exception
Adopted loanwords ❌ No Part of local vernacular

Impact on Assistive Technologies

Screen readers and language declaration:

<!-- Without lang: NVDA/JAWS pronounces "Bonjour" with English phonetics -->
<html>
<body><h1>Bonjour</h1></body>
</html>

<!-- With lang="fr": Correct French pronunciation -->
<html lang="fr">
<body><h1>Bonjour</h1></body>
</html>

Popular screen reader behavior:

Reader Without lang With wrong lang With correct lang
NVDA Uses system language Incorrect pronunciation ✅ Correct
JAWS Uses default language Wrong voice change ✅ Correct
VoiceOver Automatic inference May change voice ✅ Correct
TalkBack Uses device language Forced pronunciation ✅ Correct

International SEO: hreflang and Language Declaration

Relationship Between lang and hreflang

The lang attribute and hreflang tags work together but have different purposes⁴:

Attribute Purpose Audience
lang Declare content language Browsers, screen readers
hreflang Indicate alternate versions Search engines

Correct implementation:

<!-- English version -->
<!DOCTYPE html>
<html lang="en">
<head>
  <title>My Website</title>
  <link rel="canonical" href="https://example.com/en/">

  <!-- hreflang for international SEO -->
  <link rel="alternate" hreflang="en" href="https://example.com/en/">
  <link rel="alternate" hreflang="es" href="https://example.com/es/">
  <link rel="alternate" hreflang="pt-BR" href="https://example.com/pt-br/">
  <link rel="alternate" hreflang="x-default" href="https://example.com/en/">
</head>
<body>
  <h1>Welcome</h1>
</body>
</html>

Strategies for Multilingual Sites

URL Structure

# By subdirectory (recommended)
example.com/en/           → lang="en"
example.com/es/           → lang="es"
example.com/pt-br/        → lang="pt-BR"

# By subdomain
en.example.com/           → lang="en"
es.example.com/           → lang="es"

# By country domain
example.com/              → lang="en"
example.es/               → lang="es"
example.com.br/           → lang="pt-BR"

Implementation in Modern Frameworks

Vue 3 with Vue Router:

// router/index.ts
import { createRouter, createWebHistory } from 'vue-router'

const routes = [
  {
    path: '/:lang(en|es|pt-br)',
    children: [
      { path: '', component: Home },
      { path: 'about', component: About }
    ]
  }
]

// composables/useLanguage.ts
import { useHead } from '@vueuse/head'
import { useRoute } from 'vue-router'
import { computed } from 'vue'

export function useLanguage() {
  const route = useRoute()

  const currentLang = computed(() => {
    const lang = route.params.lang as string
    const langMap: Record<string, string> = {
      'en': 'en',
      'es': 'es',
      'pt-br': 'pt-BR'
    }
    return langMap[lang] || 'en'
  })

  useHead({
    htmlAttrs: {
      lang: currentLang
    }
  })

  return { currentLang }
}

Next.js with i18n:

// next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'es', 'pt-BR'],
    defaultLocale: 'en',
    localeDetection: true
  }
}

// pages/_document.js
import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
  return (
    <Html> {/* Next.js injects lang automatically */}
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

Nuxt 3 with @nuxtjs/i18n:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],
  i18n: {
    locales: [
      { code: 'en', iso: 'en-US', name: 'English' },
      { code: 'es', iso: 'es-ES', name: 'Español' },
      { code: 'pt-br', iso: 'pt-BR', name: 'Português' }
    ],
    defaultLocale: 'en',
    strategy: 'prefix'
  }
})
// The module handles lang automatically

Content-Language vs lang: Critical Differences

HTTP Header Content-Language

HTTP/1.1 200 OK
Content-Language: en
Content-Type: text/html; charset=UTF-8

HTML lang Attribute

<html lang="en">

Detailed Comparison

Aspect Content-Language HTTP HTML lang
Purpose Target audience of resource Content language
Reading Before parsing HTML When parsing HTML
Accessibility ❌ Not used ✅ Used by screen readers
SEO Weak signal Stronger signal
Granularity Document level only Element by element
Recommendation Optional Required (WCAG Level A)

Recommendation: Always use lang in HTML. The Content-Language header is optional and less useful.

Special Cases and Solutions

Mixed Content

<html lang="en">
<body>
  <article>
    <h1>Review: "Cien años de soledad"</h1>
    <p>This classic novel by Gabriel García Márquez is a masterpiece.</p>

    <!-- Quote from the book in Spanish -->
    <blockquote lang="es">
      <p>"Muchos años después, frente al pelotón de fusilamiento, el coronel Aureliano Buendía había de recordar aquella tarde remota en que su padre lo llevó a conocer el hielo."</p>
    </blockquote>

    <p>As we see, Márquez opens with one of literature's most famous sentences.</p>
  </article>
</body>
</html>

RTL (Right-to-Left) Languages

<!-- Arabic -->
<html lang="ar" dir="rtl">

<!-- Hebrew -->
<html lang="he" dir="rtl">

<!-- Persian/Farsi -->
<html lang="fa" dir="rtl">

RTL sections in LTR document:

<html lang="en">
<body>
  <p>This article discusses Middle Eastern cuisine.</p>

  <blockquote lang="ar" dir="rtl">
    <p>الطعام العربي لذيذ جدا</p>
  </blockquote>
</body>
</html>

Languages Without ISO 639-1 Codes

Some languages only have ISO 639-2 (3-letter) or ISO 639-3 codes:

<!-- Nahuatl (Aztec) - Only ISO 639-2/3 -->
<html lang="nah">

<!-- Mapudungun (Mapuche) - Only ISO 639-3 -->
<span lang="arn">Mari mari</span>

<!-- Sign languages -->
<video lang="ase"> <!-- American Sign Language -->

Verification and Testing

Validation Tools

  1. W3C Validator: Verifies HTML syntax including lang
  2. axe DevTools: WCAG accessibility audit
  3. WAVE: Detects language declaration errors
  4. UXR SEO Analyzer: Specific lang and SEO verification

Verification Checklist

Level A (Required)

  • [ ] <html lang="xx"> present on all pages
  • [ ] Valid language code per BCP 47
  • [ ] Declared language matches main content

Level AA (Recommended)

  • [ ] Sections in other languages have specific lang
  • [ ] Textual quotes have declared language
  • [ ] Significant language changes marked

International SEO

  • [ ] hreflang implemented for all versions
  • [ ] x-default defined for fallback
  • [ ] Consistency between lang and hreflang
  • [ ] Canonical URLs per language

How to Verify with UXR SEO Analyzer

Verify your language configuration with our extension:

  1. Install the extension UXR SEO Analyzer
  2. Navigate to your website
  3. Open the extension → “Basic SEO” tab
  4. Check “Language Declaration”

The extension detects:

  • ✅ Presence of lang attribute
  • ✅ BCP 47 code validity
  • ⚠️ Inconsistencies between declared language and content
  • ⚠️ Sections without language declaration
  • ❌ Invalid or malformed codes

Next Steps

Continue improving your multilingual implementation:

References

This article was created using official authoritative sources:

[1] W3C: Language tags in HTML and XML https://www.w3.org/International/articles/language-tags/ Complete W3C specification on BCP 47 language tags, including structure, syntax, and use cases. Authoritative reference for correct language code construction.

[2] WCAG 2.2: Success Criterion 3.1.1 Language of Page https://www.w3.org/WAI/WCAG22/Understanding/language-of-page.html WCAG Level A conformance criterion requiring programmatic language declaration for pages. Includes sufficient techniques and common failures.

[3] WCAG 2.2: Success Criterion 3.1.2 Language of Parts https://www.w3.org/WAI/WCAG22/Understanding/language-of-parts.html WCAG Level AA conformance criterion for language declaration in specific sections. Defines exceptions for technical terms and proper nouns.

[4] Google Search Central: Tell Google about localized versions https://developers.google.com/search/docs/specialty/international/localized-versions Official Google documentation on hreflang implementation and language signals for international SEO.

[5] IANA Language Subtag Registry https://www.iana.org/assignments/language-subtag-registry/ Official IANA registry with all valid language, region, script, and variant codes for use in BCP 47 tags.

Source coverage: HIGH - W3C, WCAG, Google Search Central, and IANA sources provide complete authoritative coverage.

Additional Resources


Note: This article is part of our advanced technical SEO and internationalization series. Explore all articles in the Basic SEO Hub.

Author: UXR Chile Team Last updated: December 2025 Reading time: 14 minutes

Related articles

Related version

Introduction

Language Declaration Explained

Language declaration (the attribute) is a fundamental HTML element that tells browsers, search engines, and assistive technologies the primary language of...