コンテンツ重視の静的サイトジェネレーター Astro でドキュメントサイトを構築する
Astro は SSG (Static Site Generator) の1つです。「高速でコンテンツにフォーカスした Web サイトを構築するためのオールインワン Web フレームワーク」というのがキャッチコピーです。
v1.0 がリリースされました。
ブログやポートフォリオサイトの他、ドキュメンテーションサイトのテンプレートも提供されています。公式ドキュメントには日本語版もあります。この記事では Astro の概要を見るとともに、実際にサイトを構築してみて使用感をお伝えできたらと思います。
Astro 概要
#ドキュメントの Getting Started から Key Features を引用します。
- コンポーネントアイランド: 高速なウェブサイトを構築するための新しいウェブアーキテクチャー。
- サーバーファーストのAPI設計: ユーザーのデバイスから高コストのハイドレーションをなくします。
- デフォルトでゼロJS: サイトを遅くするJavaScriptランタイムオーバーヘッドはありません。
- エッジ対応: DenoやCloudflareのようなグローバルなエッジを含め、どこでもデプロイできます。
- カスタマイズ可能: Tailwind、MDX、その他100以上のインテグレーションから選択可能です。
- 特定のUIに依存しない: React、Preact、Svelte、Vue、Solid、Litなどをサポートします。
Astro の設計思想と適用領域については、コアコンセプトのAstroを選ぶ理由 に詳しく記載されています。
- コンテンツ重視
- 近年のフロントエンドのフレームワークが Figma のような操作性重視の Web アプリケーションにフォーカスしているのに対し、Astro はコンテンツが豊富なサイト向けに設計されている
- サーバーファースト
- サーバーサイドレンダリングを最大限活用する。Next.js や Nuxt の SSR がパフォーマンス懸念への対処として限定的に使用されるのと対照的
- デフォルトで高速
- ロードが遅くなる原因となる JavaScript をクライアントで起動しない(アイランドを除く)
- 簡単に使える
- React、Svelte、Vue などの UI コンポーネント言語が使え、独自の Astro UI 言語も用意されている
- 充実した機能と柔軟性
- オールインワンであり、多くのインテグレーションにより拡張可能
最後のインテグレーションの部分ですが、Astro の Integrations のページにカタログがあります。
Netlify CMS との接続も可能となっており、コンテンツ重視のサイトで Markdown に慣れていないユーザーに使ってもらうようにすることも可能です。Netlify CMS については以下の記事で紹介しています。
コアコンセプトの MPAs vs. SPAs に Astro が採用した MPA (マルチページアプリケーション)と SPA(シングルページアプリケーション)の対比が記述されています。
サーバーレンダリングとクライアントレンダリング、サーバールーティングとクライアントルーティング、サーバー状態管理とクライアント状態管理、これらはトレードオフの関係にあり、どちらがより良い、悪いというものではなく、Astro はコンテンツに特化した Web サイトという使用目的に合致している MPA を選択したと結論づけられています。
また、Astro はサーバー言語として Ruby や PHP などの専用言語を使うことなく、JavaScript、HTML、CSS が使える点で、Next.js などモダンな Web フレームワークと同様の開発体験で MPA サイトアーキテクチャを構築できるとしています。
コアコンセプトのAstroアイランドでは、インタラクティブな UI について記載されています。ドキュメントの図を転載します。
「Astroアイランド」とは、HTMLの静的なページ上にあるインタラクティブなUIコンポーネントを指します。1つのページに複数のアイランドが存在でき、アイランドは常に孤立して表示されます。静的で非インタラクティブなHTMLの海に浮かぶ島(アイランド)とお考えください。
インタラクティブな UI を作成するため、開発者はブラウザで実行される必要のあるコンポーネントを Client Directives により 指定します。これにより必要なものだけがハイドレーション[1]されます。個々のアイランドは独立して並列にロードされ、重いものは遅延ロードされます。
アイランドアーキテクチャーは以前紹介した Deno の Fresh も採用しています。
プロジェクト生成
#プロジェクトを作成するには、以下のコマンドを実行します。
npm create astro@latest
テンプレートとしてドキュメンテーションサイトを選択しました。
Welcome to Astro! (create-astro v1.0.1)
Lets walk through setting up your new Astro project.
✔ Where would you like to create your new project? … ./astro-doc-site-example
✔ Which template would you like to use? › Documentation Site
✔ Template copied!
✔ Would you like to install npm dependencies? (recommended) … yes
✔ Packages installed!
✔ Would you like to initialize a new git repository? (optional) … yes
✔ Git repository created!
✔ How would you like to setup TypeScript? › Relaxed
✔ TypeScript settings applied!
✔ Setup complete.
✔ Ready for liftoff!
Next steps
You can now cd into the astro-doc-site-example project directory.
Run npm run dev to start the Astro dev server. CTRL-C to close.
Add frameworks like react and tailwind to your project using astro add
Stuck? Come join us at https://astro.build/chat
Good luck out there, astronaut.
VS Code でプロジェクトを開くと Astro 拡張のインストールをサジェストされますのでインストールしましょう。
ローカルの開発サーバーは以下のスクリプトで起動し、ホットリロードが有効になります。
npm run dev
ローカルに環境を構築しなくても、Web IDE で簡単に試せるようになっています。
astro.newというサイトから、テンプレートを選んで、StackBlitz、CodeSandbox、Gitpod などの Web IDE からプロジェクトを開いて試すことできます。下のスクリーンショットは、StackBlitz でプロジェクトを開いたところです。開発サーバーが起動して、プレビューで開発中の画面も確認できます。
プロジェクト構成
#ドキュメンテーションサイトの画面構成は、ヘッダー、サイドバー、コンテンツからなり、ヘッダーに検索ボックスがついた、OSS のドキュメントサイトなどによくある構成となっています。ダークモード、ライトモード切り替えのスイッチまで搭載されています。
ディレクトリ構成は以下のようになっています。src/components
に画面構成に対応するコンポーネント、src/layouts
に各コンポーネントを配置する専用のレイアウトコンポーネント、そしてメインのコンテンツは src/pages
に格納されます。
├── src
│ ├── components
│ │ ├── Footer
│ │ │ ├── AvatarList.astro
│ │ │ └── Footer.astro
│ │ ├── HeadCommon.astro
│ │ ├── HeadSEO.astro
│ │ ├── Header
│ │ │ ├── AstroLogo.astro
│ │ │ ├── Header.astro
│ │ │ ├── LanguageSelect.css
│ │ │ ├── LanguageSelect.tsx
│ │ │ ├── Search.css
│ │ │ ├── Search.tsx
│ │ │ ├── SidebarToggle.tsx
│ │ │ └── SkipToContent.astro
│ │ ├── LeftSidebar
│ │ │ └── LeftSidebar.astro
│ │ ├── PageContent
│ │ │ └── PageContent.astro
│ │ └── RightSidebar
│ │ ├── MoreMenu.astro
│ │ ├── RightSidebar.astro
│ │ ├── TableOfContents.tsx
│ │ ├── ThemeToggleButton.css
│ │ └── ThemeToggleButton.tsx
│ ├── config.ts
│ ├── env.d.ts
│ ├── languages.ts
│ ├── layouts
│ │ └── MainLayout.astro
│ ├── pages
│ │ ├── en
│ │ │ ├── introduction.md
│ │ │ ├── page-2.md
│ │ │ ├── page-3.md
│ │ │ └── page-4.md
│ │ └── index.astro
│ └── styles
│ ├── index.css
│ └── theme.css
├── public
│ ├── default-og-image.png
│ ├── favicon.svg
│ └── make-scrollable-code-focusable.js
├── astro.config.mjs
└── package.json
生成されたプロジェクトではコンポーネントの実装に Astro UI 言語が使われていますが、React や Vue などで作ることもできます。Astro のリポジトリの examples ディレクトリの flamework-* のプロジェクトが格納されているのに加え、コミュニティによるテーマやスターターキットも多く開発されています。
src/pages
に配置するコンテンツは Markdown 形式で、ヘッダーにタイトルやレイアウトファイルを指定します。
---
title: Introduction
description: Docs intro
layout: ../../layouts/MainLayout.astro
---
**Welcome to Astro!**
This is the `docs` starter template. It contains all of the features that you need to build a Markdown-powered documentation site, including:
多言語対応も可能で、README に手順が書いてあります。src/config.ts
に以下のように日本語の言語設定と対応するレイアウト情報を追加し,src/pages/ja
配下に専用のファイルを配置しました。
export const KNOWN_LANGUAGES = {
English: 'en',
+ 日本語: 'ja',
} as const;
export const SIDEBAR: Sidebar = {
en: {
'Section Header': [
{ text: 'Introduction', link: 'en/introduction' },
{ text: 'Page 2', link: 'en/page-2' },
{ text: 'Page 3', link: 'en/page-3' },
],
'Another Section': [{ text: 'Page 4', link: 'en/page-4' }],
},
+ ja: {
+ 'セクションヘッダー': [
+ { text: 'イントロダクション', link: 'ja/introduction' },
+ { text: 'ページ2', link: 'ja/page-2' },
+ { text: 'ページ3', link: 'ja/page-3' },
+ ],
+ '他のセクション': [{ text: 'ページ4', link: 'ja/page-4' }],
+ },
};
これで、UI に言語切り替えスイッチが出現して、URL を en
から ja
に切り替えると日本語コンテンツが表示されます。
多言語対応、いい感じなのですが、テンプレートから生成される言語切り替えのセレクトボックスは残念ながらちゃんと動作しませんでした。issue を起票しておこうと思います。Astro 本家のドキュメントサイトの実装を見たら、テンプレートとはかなり違ってました。
2023.01.29 追記
Astro 2.0 ではちゃんと動作しました。
この言語切り替えの UI や検索ボックスなどは、client ディレクティブが付与されており、ハイドレートされたアイランドとして動作します。
デプロイしてみる
#ドキュメントの「デプロイ」には、静的にデプロイする手順が書かれています。GitHub Pages、Netlify、Google Clund Run、Firebase、Vercel、Cloudeflare Pages などのターゲットにデプロイする手順が書かれています。
Netlify にデプロイしてみました。
プロジェクトルートに以下の内容で netlify.toml ファイルを追加します。
[build]
command = "npm run build"
publish = "dist"
プロジェクトを GitHub のリポジトリとしてプッシュし、Netlify の Web UI でデプロイを実行します。Netlify 側で Astro の設定を自動検出するため、リポジトリを接続する以外に UI で設定することは特にありません。
デプロイされたサイトです。
https://kondoumh-astro-doc-site-example.netlify.app/
GitHub のリポジトリは以下にあります。
GitHub - kondoumh/astro-doc-site-example
この記事では、SSG としての利用しかしておらず、Astro の SSR の機能は未使用です。SSR を有効にするには、各サービスのアダプターを使用する必要があります。Cloudflare、Deno、Netlify、Vercel の各エッジサービスと Node.js 用のアダプターが提供されています。
SSR を有効化すると、リクエストヘッダー、リダイレクト、レスポンス、API Routes などの機能を使用でき、ログイン処理やサーバーサイドでのコード実行が可能となります。
まとめ
#Astro は、コンテンツ重視の MPA アーキテクチャによる次世代 SSG でした。技術面もさることながら、ドキュメントにコンセプトが熱く語られているところ、簡単に使えることに注力しており Web IDE で即座に試せるところなどユーザー獲得の施策にも力が入っています。豊富なテンプレートも用意されていて、さまざまな用途のサイトを構築できるパワーを感じます。
クライアントサイドで DOM の変更を行うクライアントサイドのプロセス ↩︎