Mapboxでi18nと連携して、言語設定を切り替える

JAボタンまたは、ENボタンをクリックすると、サイトの言語設定が切り替わり、合わせてMapboxの言語設定も切り替えれるようにします。

こんなコンポーネントをつくります。

本記事のNextjsのバージョンは”14.0.4″、react-map-gl、i18nを導入済みの前提で進みます。

mapboxの言語設定の導入と、i18nの導入は、こちらの記事を参考にしてください。

目次

言語の型定義

日本語、英語の切り替えをします。
他の言語も必要な場合は、型定義に追加しましょう。

export const enum LOCALE {
  JA = 'ja',
  EN = 'en'
}

export type Locale = LOCALE.JA | LOCALE.EN

言語切替コンポーネント

言語切り替えは関数の中で、下記2点を行います。
・i18nの言語を切り替える
・Mapboxの言語を切り替える

i18nの言語切り替え

i18nの言語切り替えはchangeLanguageを呼び出すことで実現できます。

第一引数に切り替えたい言語を渡します。

i18n.changeLanguage(LOCALE.JA)

https://www.i18next.com/overview/api#changelanguage

Mapboxの言語切り替え

MapboxはsetStyleにMapboxLanguageを設定することで切り替えができます。

map?.getMap().setStyle(new MapboxLanguage().setLanguage(map?.getMap().getStyle(), LOCALE.JA))

https://docs.mapbox.com/mapbox-gl-js/api/map/#map#setstyle

言語切り替えボタンコンポーネント

コード全体はこちらです。

LangBtnをクリックすると、handleLanguageChangeを呼び出して、i18nとMapboxの言語切り替えを行います。

これにより、サイト全体の言語切り替えをできるようにします。

import { LOCALE, Locale } from '@/types/Lang'
import MapboxLanguage from '@mapbox/mapbox-gl-language'
import { useRouter } from 'next/router'
import { useTranslation } from 'react-i18next'
import { useMap } from 'react-map-gl'
import styled from 'styled-components'

export function LangButtons() {
  const router = useRouter()
  const { locale } = useRouter()
  const { i18n } = useTranslation('translation', { lng: locale })
  const { map } = useMap()

  const handleLanguageChange = (lang: Locale) => {
    i18n.changeLanguage(lang)
    map?.getMap().setStyle(new MapboxLanguage().setLanguage(map?.getMap().getStyle(), lang))

    const newPath = `${lang === LOCALE.JA ? '' : `/${LOCALE.EN}`}${router.pathname}`
    const newUrl = { pathname: newPath, query: router.query }

    router.push(newUrl, undefined, { shallow: true, locale: lang })
  }

  return (
    <BtnBox>
      <LangBtn onClick={() => handleLanguageChange(LOCALE.JA)}>{LOCALE.JA.toUpperCase()}</LangBtn>
      <Slash>/</Slash>
      <LangBtn onClick={() => handleLanguageChange(LOCALE.EN)}>{LOCALE.EN.toUpperCase()}</LangBtn>
    </BtnBox>
  )
}

const BtnBox = styled.div`
  display: flex;
  gap: 0 8px;
  padding-bottom: 4px;
`

const LangBtn = styled.button`
  color: inherit;
  background-color: transparent;
  border: none;
  cursor: pointer;
  outline: none;
  padding: 0;
  appearance: none;
  font-size: 16px;
  font-family: inherit;
`

const Slash = styled.span`
  font-size: 14px;
  font-weight: bold;
`

Summary

コロナが明け、インバウンドが戻りつつある今。多言語化の重要さは増してきているように見えます。

本サイトも何かのお役に立てば。

よかったらシェアしてね!
目次