question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Setting <html lang="..."> by default

See original GitHub issue

I’m wondering if there is any way to implicitly set the lang attribute to the html tag. This is a good practice, which improves SEO and a11y.

Currently, my workaround is roughly this:

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

export default class MyDocument extends Document {
  render() {
    return (
      <html lang={this.props.__NEXT_DATA__.props.initialLanguage}>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    )
  }
}

If there is no way to inject lang automatically, shall it be mentioned in the example or plugin docs?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:9
  • Comments:44 (30 by maintainers)

github_iconTop GitHub Comments

6reactions
eric-burelcommented, Jul 15, 2020

Ok so a more robust code is as follow:

// i18next-http-middleware is in charge of enhancing the req object
interface IncomingMessageWithI18n extends IncomingMessage {
  language?: string;
  i18n: any;
}
export const i18nPropsFromCtx = (
  ctx: NextPageContext
): Partial<HtmlLanguageProps> => {
  if (!(ctx && ctx.req && (ctx.req as IncomingMessageWithI18n).language))
    return {};
  const req = ctx.req as IncomingMessageWithI18n;
  return {
    lang: req.language,
    dir: req.i18n && req.i18n.dir(req.language),
  };
};

and in plain JS:

export const i18nPropsFromCtx = (ctx) => {
  if (!(ctx && ctx.req && ctx.req.language))
    return {};
  const req = ctx.req;
  return {
    lang: req.language,
    dir: req.i18n && req.i18n.dir(req.language),
  };
};

Use that in your custom _document getInitialProps call:

MyDocument.getInitialProps = async (ctx) => {
  const i18nDocumentProps = i18nPropsFromCtx(ctx);
  return {
    i18nDocumentProps,
  };
};

and then finally:

export default class MyDocument extends Document {
  render() {
    const { i18nDocumentProps } = this.props;
    return (
      <Html
        {...i18nDocumentProps}
      >
....

Thanks all for your fast answers!

5reactions
felixmoshcommented, Nov 26, 2019

I’ve found out that i18next-express-middleware that is applied by next-i18next-middleware is attaching language & languageDirection on res.locals.

So the code may look like:

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx);
    const {
      res: { locals },
    } = ctx;
    const additionalProps = {
      languageDirection: locals.languageDirection,
      language: locals.language,
    };

    return { ...initialProps, ...additionalProps };
  }

  render() {
    const { languageDirection, language } = this.props;
    return (
      <html lang={language} dir={languageDirection}>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    );
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Declaring language in HTML - W3C
Quick answer. Always use a language attribute on the html tag to declare the default language of the text in the page. This...
Read more >
What is the default value <html lang="???"> - Stack Overflow
The lang attribute value of the node or an ancestor. The pragma-set default language. HTTP headers (or details from some other protocol if...
Read more >
lang - HTML: HyperText Markup Language - MDN Web Docs
Note: The default value of lang is unknown , therefore it is recommended to always specify this attribute with the appropriate value.
Read more >
How to fix: Consider adding a “lang” attribute to the “html” start ...
Always use a language attribute on the <html> tag to declare the default language of the text in the page, using the lang...
Read more >
Setting a default language for the HTML tag - Episerver Support
The HTML lang attribute can be used to declare the language of a Web page or a portion of a Web page. This...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found