Fix Missing HTML Lang Attribute for Better Accessibility

Learn how to fix missing lang attribute in Lighthouse accessibility audits. The lang attribute helps screen readers pronounce content correctly.
Harlan WiltonHarlan Wilton4 min read Published

Without a language declaration, screen readers guess the page language based on user settings. If they guess wrong, content becomes incomprehensible.

What's Happening

The lang attribute on the <html> element tells browsers and assistive technologies what language the page content is in. Screen readers use this to load the correct pronunciation rules, speech patterns, and voice.

When the lang attribute is missing, a screen reader assumes the user's default language. A French page read with English pronunciation rules produces nonsensical audio. Even for English pages, missing the lang attribute can affect hyphenation, quotes, and other language-specific features.

Diagnose

DevTools

  1. Open DevTools (F12)
  2. Elements panel > select the <html> element
  3. Check if lang attribute exists with a valid value

Quick console check:

const lang = document.documentElement.lang
if (!lang) {
  console.error('HTML element is missing lang attribute')
}
else {
  console.log('Page language:', lang)
}

View Page Source

  1. Right-click > View Page Source
  2. First line after <!DOCTYPE html> should be <html lang="...">

Fix

1. Add Lang Attribute to HTML Element

Add the lang attribute to your <html> element:

<!DOCTYPE html>
<html lang="en">
<head>
  ...
</head>
<body>
  ...
</body>
</html>

2. Use Correct Language Codes

Use BCP 47 language tags:

<!-- Basic language codes -->
<html lang="en">      <!-- English -->
<html lang="es">      <!-- Spanish -->
<html lang="fr">      <!-- French -->
<html lang="de">      <!-- German -->
<html lang="ja">      <!-- Japanese -->
<html lang="zh">      <!-- Chinese -->

<!-- With regional variants -->
<html lang="en-US">   <!-- American English -->
<html lang="en-GB">   <!-- British English -->
<html lang="pt-BR">   <!-- Brazilian Portuguese -->
<html lang="zh-Hans"> <!-- Simplified Chinese -->
<html lang="zh-Hant"> <!-- Traditional Chinese -->

3. Handle Mixed-Language Content

When content switches language within the page, use lang on specific elements:

<html lang="en">
<body>
  <p>The French phrase <span lang="fr">c'est la vie</span> means "that's life".</p>

  <blockquote lang="de">
    Die Grenzen meiner Sprache bedeuten die Grenzen meiner Welt.
  </blockquote>
  <p>— Ludwig Wittgenstein</p>
</body>
</html>

Screen readers will switch pronunciation rules for the marked sections.

Framework Examples

NuxtSet the default language in nuxt.config.ts:
export default defineNuxtConfig({
  app: {
    head: {
      htmlAttrs: {
        lang: 'en'
      }
    }
  }
})
For dynamic language:
<script setup>
// In your layout or page
const { locale } = useI18n()

useHead({
  htmlAttrs: {
    lang: locale.value
  }
})
</script>
With @nuxtjs/i18n, this is handled automatically based on the current locale.
React / Next.jsIn Next.js App Router, set in layout:
// app/layout.tsx
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
For dynamic language:
// app/[locale]/layout.tsx
export default function LocaleLayout({ children, params }) {
  return (
    <html lang={params.locale}>
      <body>{children}</body>
    </html>
  )
}
With Pages Router, customize _document.js:
// pages/_document.js
export default function Document() {
  return (
    <Html lang="en">
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

Verify the Fix

  1. Re-run Lighthouse - The "<html> element has a [lang] attribute" audit should pass
  2. Console verification:
const lang = document.documentElement.lang
console.log('Lang attribute:', lang || 'MISSING')
console.log('Valid:', /^[a-z]{2,3}(-[A-Za-z]{2,4})?$/.test(lang))
  1. Screen reader test - The page should be read with correct pronunciation for the declared language

Common Mistakes

  • Lang on body instead of html — Must be on <html>, not <body>. The lang attribute on body is ignored by most tools.
  • Invalid language code<html lang="english"> is invalid. Use proper BCP 47 codes like en.
  • Empty lang attribute<html lang=""> fails the audit. Must contain a valid code.
  • Wrong language — Setting lang="en" on a French page is worse than no lang at all. Screen readers will mispronounce everything.
  • Forgetting regional variants — For content with regional spelling or vocabulary differences, consider en-US vs en-GB, pt-PT vs pt-BR.

HTML lang issues often appear alongside:

  • Document Title — Both are document-level requirements set in the head
  • Heading Order — Proper lang ensures headings are pronounced correctly
  • Hreflang — Multi-language sites need both html lang and hreflang

Test Your Entire Site

Missing lang attributes often occur in error pages, legacy templates, or dynamically generated pages that bypass your main layout. Unlighthouse scans every page on your site and flags any missing lang attributes, ensuring consistent accessibility across all routes.