🏗️

Astroサイトを多言語対応・LP機能付きにリニューアルした話

に公開

はじめに

個人で運営しているOSSプロジェクト紹介サイト「Asopi Tech」を大幅にリニューアルしました。以前はシンプルなブログサイトでしたが、OSSプロジェクトの数が増えてきたことや、各プロジェクトの詳細を紹介したいという思いから、サイト全体を見直すことにしました。

今回は新しいサイト構造と、リニューアルで活用したAstroの機能を紹介します。

リニューアルで追加した機能

主な変更点は以下の通りです:

  • 多言語対応(日本語/英語)
  • OSSプロジェクト紹介ページの追加
  • サービス詳細LP(ランディングページ)の実装
  • ナビゲーション・フッターの刷新

3つのOSSプロジェクト

今回のリニューアルでは、現在絶賛開発中の3つのOSSプロジェクトを中心にサイトを構成しました。以下に各プロジェクトをご紹介いたします。

Alopex DB - 統一データベースエンジン

「1ファイル、5モード、無限スケール」

Alopex DBは、同じデータファイルで組み込み→サーバー→クラスタとシームレスにスケールできるデータベースです。

解決する課題
アプリケーション開発では用途やプロジェクトの規模に応じてSQLiteのような組み込みDB、ベクトル検索エンジン、RDB、データベースのクラスタなど様々なデータモデルやスケール形態を必要としています。これらすべてに別々の製品、別々の接続方法と開発、別々の製品のセットアップとインフラ管理、そしてスケール変更時には別製品へのアーキテクチャ再設計とデータのコンバートという吐血レベルの苦痛があります。

主な特徴

  • 同じデータファイルであらゆるモード間をシームレス移行(WASM、Embedded、Single-Node、Replicated、Distributed)
  • DB製品切り替え時のデータ変換・マイグレーションが完全不要
  • RaftベースKVSをコアに、SQL、ベクトル検索、グラフETLを単一エンジンで統合
  • 超高速なメッセージングフレームワークをベースにしたRaft拡張アルゴリズムにより分散ACIDトランザクションを実現します。
  • Pure Rust実装、WebAssembly対応

技術スタック:Rust, LSM-Tree, MVCC, Raft Consensus, HNSW/IVF/Flat Vector Index

現在Pre-Alpha段階で開発中です。

https://github.com/alopex-db/alopex

JV Language - Java糖衣構文トランスパイラ

「Java糖衣構文、ゼロランタイム」

JV言語は、Java糖衣構文でPython・Julia・Kotlin並みの使い勝手を実現するトランスパイラです。

解決する課題
Javaは堅牢だが冗長。Python/Juliaは書きやすいが本番運用なんて気絶しそう。Kotlinは良いがまた別の開発ツールなどが必要。

主な特徴

  • すべてのJVコードが純粋なJavaソースファイルに変換される
  • 追加ランタイム不要、既存JVMでそのままコンパイル・実行可能
  • 生成されたJavaは可読で、直接編集可能
  • 統計・機械学習ライブラリ、Excel関数互換関数(VLOOKUP、SUMIF等)を標準サポートし、算術・財務の機能を超強化

技術スタック:純Java, トランスパイラ, LSP Server, MCP Server

https://github.com/project-jvlang

HC GraphRAG - AWS向けGraphRAG

「AWSで動くGraphRAG」

HC GraphRAGは、Microsoft ResearchのGraphRAGをAWSインフラ向けに移植したプロジェクトです。

解決する課題
標準的なRAGは単純なベクトル検索ではエンティティ間の関係を見逃し、複数ドキュメントをまたいだマルチホップ推論を必要とする複雑なクエリに苦戦します。公式のMicrosoft GraphRAGはAzure OpenAIが必須という制約もあります。

主な特徴

  • AWS Bedrock + Anthropicモデルを使用(Azure OpenAI依存なし)
  • EC2 / Fargateデプロイ対応
  • Leidenアルゴリズムによる階層的コミュニティ検出
  • ローカル・グローバル・ハイブリッド検索モード
  • 2つの実装:Python(LlamaIndex)とJava(ONNX + GraalVM Native Image)

技術スタック

  • Python実装:LlamaIndex, Anthropic Claude, LanceDB
  • Java実装:ONNX Runtime, AWS Bedrock, GraalVM Native Image

https://github.com/asopitech/graphrag-anthropic-llamaindex
https://github.com/hc-graphrag/java-core

サービス詳細LP

各プロジェクトには専用の詳細LP(ランディングページ)を用意しました:

  • /services/alopex-db - Alopex DBの詳細
  • /services/project-jv - JV言語の詳細
  • /services/hc-graphrag - HC GraphRAGの詳細

これらのLPは、以下のセクションで構成されています:

セクション 内容
Hero プロジェクト概要とCTA
Challenge 解決しようとしている課題
Outcome 提供する価値
Capabilities 機能・特徴
Tech Stack 技術スタック
Proof 開発状況・リソース

ブログページ

ブログは従来通り /blog で提供していますが、新しく多言語対応を追加しました。

  • 日本語: /blog
  • 英語: /en/blog

コンテンツが片方の言語にしかない場合は、フォールバック機能で対応言語のコンテンツを表示するようにしています。

Aboutページ

/about では、GitHubリポジトリからデータを取得して、プロジェクトの情報を動的に表示しています。

Contactページ

/contact では、X(Twitter)とGitHub Issuesへの問い合わせ導線を用意しています。

多言語対応

今回のリニューアルで最も大きな変更の一つが多言語対応です。

URLの構造は以下のようになっています:

  • 日本語(デフォルト): /, /blog, /services など
  • 英語: /en, /en/blog, /en/services など

サイトのナビゲーションやフッター、各ページのコピーなど、すべてのテキストが日本語と英語に対応しています。

フッターの刷新

フッターも刷新しました。以下の3つのセクションで構成されています:

  1. サイト - ホーム、サービス、ブログ、About、Contactへのリンク
  2. プロジェクト - 各OSSプロジェクトへの直接リンク
  3. リンク - X、GitHub Issues、各プロジェクトのドキュメントサイトへのリンク

外部リンクには適切に target="_blank"rel="noopener noreferrer" を設定して、セキュリティにも配慮しています。


技術解説

ここからは、リニューアルで活用したAstroの機能を技術的に解説します。

Content Collections による型安全なコンテンツ管理

ブログ記事だけでなく、サイトのコピー(テキスト)やナビゲーション設定もContent Collectionsで管理しています。

src/content/config.ts
const blog = defineCollection({
  type: 'content',
  schema: z.object({
    locale: z.enum(['ja', 'en']).default('ja'),
    title: z.string(),
    description: z.string(),
    // ...
  }),
});

// JSONやYAMLファイルも type: 'data' で管理可能
const copy = defineCollection({
  type: 'data',
  schema: z.object({
    locale: z.enum(['ja', 'en']),
    namespace: z.string(),
    entries: z.record(z.string(), z.string()),
  }),
});

locale フィールドを追加することで、同じコレクション内で日本語記事と英語記事を管理できます。

多言語(i18n)対応

Astroの組み込みi18nはルーティング設定がメインなので、テキスト取得は自前で実装しました。

src/lib/i18n.ts
export async function t(locale: SupportedLocale, key: string): Promise<TranslationResult> {
  const copy = await loadCopy(locale);
  if (key in copy) {
    return { value: copy[key], resolvedLocale: locale, isFallback: false };
  }
  // 見つからなければデフォルトロケールにフォールバック
  const fallbackCopy = await loadCopy(DEFAULT_LOCALE);
  return { value: fallbackCopy[key] ?? key, resolvedLocale: DEFAULT_LOCALE, isFallback: true };
}

動的ルーティングによるLP生成

サービスページは [slug].astro で動的に生成しています。

src/pages/services/[slug].astro
---
export async function getStaticPaths() {
  const services = await getCollection('services', (entry) => entry.data.locale === 'ja');
  return services.map((service) => ({
    params: { slug: service.data.serviceId },
    props: { service },
  }));
}
---

パフォーマンス最適化

技術 用途
Partytown Google Analyticsなどをメインスレッドから分離
Astro Image WebP変換・リサイズの自動化
Satori OG画像の自動生成
Pagefind 静的サイト内検索
Alpine.js 軽量なメニュー開閉(約15KB)

まとめ

今回のサイトリニューアルでは、Astroの様々な機能を活用しました:

  • Content Collections で型安全なコンテンツ管理
  • i18n対応 でグローバルなサイト展開
  • 動的ルーティング で効率的なページ生成
  • Partytown でパフォーマンス最適化

Astroは静的サイト生成に特化しつつも、多言語対応やLP生成など、これだけの機能を提供してくれるありがたいフレームワークです。

何か参考になれば幸いです!

Discussion