html
tag accepts lang
attribute that is, according to MDN, very important for accessibility and accessible technologies like screen readers.
Providing a lang attribute with a valid IETF identifying language tag on the element will help screen reading technology determine the proper language to announce.
Add lang="en"
by default and provide a simple way to configure the language for the whole project.
We've ended overriding the _document.js
as of https://github.com/zeit/next.js#custom-document but not providing this by default contributes to even worse web accessibility situation.
Google Chrome shows "Translate this page" dialog without the lang
set.
IMHO setting lang="en"
by default can make things worse for non-English Next.js websites. Setting it in _document.js
seems to be the right way. This is what I do and I don't feel bothered 🤷♂️
I assume most next.js user don't bother overriding _document.js
.
Assuming all pages are english would be wrong imo. For reference there's a large number of Next.js sites in basically every major language you can think of.
Making it easier to configure something like that would be interesting to pursue. cc @devknoll let's keep this in mind with the next/head
deprecation.
Thinking more broadly, react-helmet
provides a facility for supplying arbitrary attributes to html
and body
within its equivalent of Head
on any page.
To come back to my earlier comment, RFC for deprecating next/head is here: #8981
this fails on lighthouse CI with a default create-next-app and seems easy to fix
It would be nice to not have to override pages/_document.js
and just add something to next’s config.
+1 lang is important
+1 it's important
Please don't spam the thread with +1. Use the GitHub emoji reaction system to add a 👍 on the initial issue.
Perhaps this is a bit out of scope, but for multi-domain deployments (.com, .nl, .pt) it would also be kind of nice to add the lang
tag without having to implement a custom server either.
Anyone managed to set <Html lang={someLang}>
when using getServerSideProps
or getStaticProps
when the language changes between pages? Right now the _document.js
is only set on first load, from there it is not set again. That means the language prop from my pages will never change in the _document.js
file.
Right now i am using getServerSideProps
like this. Where i set the language on the page, and then extract the language in _document.js
from __NEXT_DATA__
and set it on the <Html lang={langHere}>
export async function getServerSideProps(context) {
const pageContent = await getSomePageContent(context.params)
return {
props: {
language: getLanguageFromParams(context.params),
pageContent,
},
}
}
@timneutkens The documentation does not mention any solution on how to set the language again?
Using getServerSideProps
will lose the benefit of static optimization unless you're using it already.
The following approach is to set different lang
attributes for different pages using _document.js
's getInitialProps
for SEO.
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
const { pathname } = ctx;
const lang = pathname.startsWith("/de") ? "de" : "en";
return { ...initialProps, lang };
}
render() {
const { lang } = this.props;
return (
<Html lang={lang}>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
Then, update the lang
attribute with the help of useRouter
hook in _app.js
for client-transitions:
function MyApp({ Component, pageProps }) {
const { pathname } = useRouter();
const lang = pathname.startsWith("/de") ? "de" : "en";
useEffect(() => {
document.documentElement.lang = lang;
}, [lang]);
return <Component {...pageProps} />;
}
But this approach would only work if browsers and screen readers will pick up dynamically set lang
attribute.
Is there any recommendation on how to set the HTML language when using getstaticprops / path? We can prerender all of our pages and have the active language set as param. page.de/en/products/XXX
or page.de/de/products/XXX
- so the language is available as prop. Just curious if we could set the language during static build time.
Using
getServerSideProps
will lose the benefit of static optimization unless you're using it already.The following approach is to set different
lang
attributes for different pages using_document.js
'sgetInitialProps
for SEO.class MyDocument extends Document { static async getInitialProps(ctx) { const initialProps = await Document.getInitialProps(ctx); const { pathname } = ctx; const lang = pathname.startsWith("/de") ? "de" : "en"; return { ...initialProps, lang }; } render() { const { lang } = this.props; return ( <Html lang={lang}> <Head /> <body> <Main /> <NextScript /> </body> </Html> ); } }
Setting through getInitialProps
won't work for dynamic routes.
FYI, I developed a work around on my project for this.
I used the opengraph meta "og:locale" to define the local for each page and then in my custom Document
I search it.
This is my code :
```
export default class CustomDocument extends Document
const initialProps: DocumentInitialProps = await Document.getInitialProps(ctx);
const ogLocaleMeta = initialProps.head
? initialProps.head.find((e) => e && e.type === "meta" && e.props.name === "og:locale")
: null;
return { ...initialProps, lang: ogLocaleMeta ? localeToLang[ogLocaleMeta.props.content] : null };
}
render() {
return (
Hope it can helps someone else :)
This will be handled by https://github.com/vercel/next.js/discussions/17078
document.documentElement.lang = 'yourlang'
You can add this yourself in _document.js & the new internationalization feature handles it automatically: https://nextjs.org/docs/advanced-features/i18n-routing#search-engine-optimization
I think we can close this @Timer?
Most helpful comment
It would be nice to not have to override
pages/_document.js
and just add something to next’s config.