How to set HTML lang attribute dynamically on NextJs Document?
Solution 1
Using document object the lang attribute can be set like this:
var language= ...
switch (language) {
case en: document.documentElement.lang = 'en-us'; break;
...
}
This lang attribute will not be set on the initial html, before page is hydrated, but will still pass chrome "hreflang" audit check.
Solution 2
Next 10 supports Internationalized Routing and will add lang
dynamically leaving you with:
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
Solution 3
I believe the best solution here is to use a custom ./pages/_document.js
file and override the document itself.
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}
render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
More explanation can be found here: https://nextjs.org/docs/advanced-features/custom-document
Solution 4
If you use next/head you can set the language to the html tag. Anything that you pass to the Head component will be either placed in the <head>
or <html>
.
Next Head works similar to React Helmet, so for your case you could do something along these lines:
- Create a component and import Head from "next/head"
- Inside the Head tag you add the
<html lang={lan} />
to the component.
Then you can pass the desired language to that component, then import the component on the desired pages.
import React from "react"
import Head from "next/head"
const Language = ({title, lang}) => (
<Head>
<html lang={lang} />
<title>{title}</title>
</Head>
)
export default Language
That html bit will be injected inside the <html>
tag.
Note that even if we inject it like this the console will log the following error: TypeError: n is null
.
Solution 5
I implemented this by adding this to next.config.js file:
i18n: {
// These are all the locales you want to support in
// your application
locales: ['en-US'],
// This is the default locale you want to be used when visiting
// a non-locale prefixed path e.g. `/hello`
defaultLocale: 'en-US' }
I didn't have the need to create a custom _document.js
MiguelSlv
Product Engineer for Printing and Finishing Industry, since 1998. Personal projects: Chat Player - Android App. Outdoor Navigator - Fancy iOS app. Guia Condominio - Self-Managed Home Owners Associations site Home site : https://byte-artisan.com My favorite quote: "Simplicity is the ultimate sophistication" Leonardo da Vinci
Updated on July 09, 2022Comments
-
MiguelSlv almost 2 years
I have a multi language site and need to set up the HTML lang attribute according the language for the each page.
I try to pass the value in context, but does not update when page changes.
Here the current code:
import Document, { Html, Head, Main, NextScript } from 'next/document' import GlobalContext , {eLanguage }from '../components/GlobalContext' //my global context export default class MyDocument extends Document { static async getInitialProps(ctx) { const initialProps = await Document.getInitialProps(ctx) return { ...initialProps } } static contextType = GlobalContext; render() { console.debug('Started') console.debug('language:'+ this.context.language) return ( <Html lang={eLanguage[this.context.language]}> //if the first page loaded as lang 'en' it sets 'en' and apply to all other pages. <Head> </Head> <body> <Main /> <NextScript /> </body> </Html> ) }
}
Update: The language of each page can be inferred from the page route
-
MiguelSlv almost 4 yearsI got this error on the console:head-manager.js?0ea4:2 Warning: next-head-count is missing. err.sh/next.js/next-head-count-missing. In either case, that hist is not a way to go.
-
MiguelSlv almost 4 yearsAlso note that Html tag is parent of Head tag. i don't thing Head component it means to be used in this way.
-
Gabriel Linassi almost 3 yearsThanks, this is the right answer. Same as provided in the nextjs docs.
-
ArneHugo over 2 years@GabrielLinassi, this is not quite the same as in the docs, where it says you should do this in _document. Doing it elsewhere technically works, though perhaps you can't rely on it to keep working, and it gives the console waning
Warning: next-head-count is missing
as mentioned above. -
Gabriel Linassi over 2 years@ArneHugo That's right. Thanks for the correction. I checked here on my code and it's defined on the _document as well.
-
Gangula over 2 yearsFor future readers, this is not currently supported if you're using SSG via
next export
- Reference and Documentation -
JasonGenX about 2 yearscareful, that ALONE would get you 404 on every single page.
-
itsjavi about 2 yearsthis is not SEO friendly unfortunately
-
ImanGM almost 2 years@MiguelSlv <Head> component in _document.js is different than <Head> component that we use to update <head> content. <Head> inside _document.js is being imported from 'next/document' and <Head> inside pages are being loaded from 'next/head'