AstroJavaScriptMarkdoc

Astro&Markdown/Markdocで作ったサイトで、簡単な言語切り替え機能を実装する

個人のポートフォリオサイトを、2023年からAstroで構築しています。 サイトの要件として、「日本語でも英語でも表示すること」があったため、勉強も兼ねてある程度自前で実装してみました。 基本方針 英語をベースとする 日 […]

広告ここから
広告ここまで

個人のポートフォリオサイトを、2023年からAstroで構築しています。

サイトの要件として、「日本語でも英語でも表示すること」があったため、勉強も兼ねてある程度自前で実装してみました。

基本方針

  • 英語をベースとする
  • 日本語の場合、hidetaka.dev/ja-JP/をベースURLにする
  • Markdown / Makdocファイルは、言語ごとに用意する
  • サードパーティの多言語対応ライブラリは、あえて使わない

言語別に用意したMarkdown/Markdocファイルを、言語別に読み込む

今回は配置するファイルもあまり多くないため、次のようなシンプルなディレクトリ構成とします。

src/contents/blog/hello.mdoc
src/contents/blog/hello-ja.mdoc

Astroのsrc/component/Hello.astroファイルを作成しましょう。

Astro.props.langで言語を受け取る形とし、getEntryBySlugのファイルパスを変化させます。

---
import { getEntryBySlug } from 'astro:content';

const { lang = 'en' } = Astro.props;
const entry = await getEntryBySlug('blog', `hello${/ja/.test(lang) ? '-ja' : ''}`);
---

{Content ? (
    <Content />
): null}

URLのパスから言語を判定する

今回のサイトでは、次のようにURLで言語を判定します。

  • example.com/: English
  • example.com/ja-JP: Japanese

pathnameから取得するため、ヘルパー関数を用意しましょう。

export function getLanguageFromURL(pathname: string) {
    // ja,en,es
    //const langCodeMatch = pathname.match(/\/([a-z]{2}-?[a-z]{0,2})/);
    // ja-JP, en-US
    const langCodeMatch = pathname.match(/^\/(\w{2})-([\w-]{2,})/);
    return langCodeMatch ? langCodeMatch[1] : 'en-US';
}

あとはsrc/pages以下のファイルで、言語を取得する様に実装します。

const currentPage = new URL(Astro.request.url).pathname;
const lang = getLanguageFromURL(currentPage);

言語ごとのページファイルを作成する

動的に設定できるのが理想だとは思いますが、2言語だけなので物理で押し通します。

src/pages以下に言語ごとにファイルを作成し、併せてsrc/containerssrc/componentsにページ用のファイルも用意しましょう。

src/pages/index.astro
src/pages/ja-JP/index.astro
src/containers/pages/IndexPage.astro

ページで表示するコンテンツ自体は全てページ用ファイルに任せ、src/pagesのファイルは言語の取得とコンポーネントの呼び出しのみを行います。

---
import { getLanguageFromURL } from "../../libs/urlUtils/lang.util"
import IndexPage from "../../containers/pages/IndexPage.astro";

const currentPage = new URL(Astro.request.url).pathname;
const lang = getLanguageFromURL(currentPage);
  
---

<IndexPage lang={lang} />

言語切り替え機能を実装する

最後に言語切り替え方法です。

こちらもAstro.request.urlから取得したpathnameを元に、URLを書き換える関数を作ります。

export const changeLanguageURL = (pathname: string, targetLang: 'en-US' | 'ja-JP' = 'en-US'): string => {
    const lang = getLanguageFromURL(pathname)
    if (lang === targetLang) return pathname
    if (lang === 'en-US') {
      return `/${targetLang}${pathname}`
    }
    const replaceTarget = targetLang === 'en-US' ? '' : `/${targetLang}`
    return pathname.replace(/^\/(\w{2})-([\w-]{2,})/, replaceTarget)  
}

あとはリンクタグにこの関数の実行結果を渡しましょう。

---
import { changeLanguageURL } from "../../../libs/urlUtils/lang.util";

const { pathname } = new URL(Astro.request.url)
---

<nav>
    <ul>
        <a href={changeLanguageURL(pathname, 'ja-JP')}>Japanese</a>
        <a href={changeLanguageURL(pathname, 'en-US')}>English</NavIatem>
    </ul>
</nav>

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts