概要
Next.js単体で多言語対応できるようになってるので、試してみました。(ちなみに、以前まではNext.jsの多言語対応には next-i18-next を使っていました。) 設定は公式の通りとても簡単で、各コンポーネント内でのlocale情報はuseRouterから取得できるようになっています。 1点、HTMLタグに lang を設定するのをどうやろうか少し考えた結果、無駄骨だったのでメモを残しておきます。
余談
htmlのlangをみて、日本語のときだけ、一部テキストにtext-align: justify;をかけたりします。
html[lang=ja] .text-justify {
text-align: justify;
}
結論
_document.tsのrender() で __NEXT_DATA__からlocaleを取得できる。
pages/_document.tsximport Document, {
Html,
Head,
Main,
NextScript,
DocumentContext,
DocumentInitialProps,
} from 'next/document'
class imDocument extends Document {
static async getInitialProps(
ctx: DocumentContext
): Promise<DocumentInitialProps> {
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
render(): JSX.Element {
const { locale } = this.props.__NEXT_DATA__
return (
<Html lang={locale} dir="ltr"> {
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
今まで__NEXT_DATA__をちゃんと理解してなかった。
サーバーサイドからのデータがここに入るらしく、ページのソースから見えちゃうので、逆に出ちゃ駄目なデータが入らないように気を付けないと。
おまけ、最初にやったこと
ctxからlocaleを取得して render に渡そうと考えた結果
pages/_document.tsximport Document, {
Html,
Head,
Main,
NextScript,
DocumentContext,
DocumentInitialProps,
} from 'next/document'
type Props = DocumentInitialProps & {
locale: string
}
class MyDocument extends Document {
static async getInitialProps(
ctx: DocumentContext
): Promise<Props> {
const initialProps = await Document.getInitialProps(ctx)
return {...initialProps, locale: ctx?.locale || 'ja' }
}
render(): JSX.Element {
return (
<Html lang={this.props.locale} dir="ltr"> {
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument