Astro を使ってブログを再構築する: ステップバイステップガイド
はじめに
Astro は、革新的な機能とパフォーマンスの向上により注目を集めている モダンな静的サイトジェネレーター (SSG) です。この記事では、Astro を使用したブログ再構築のセットアッププロセスと実装方法について詳しく解説します。
Astro の特徴
Astro は、パフォーマンスと柔軟性 に重点を置き、Web 開発を簡略化します。注目すべき 2 つの特徴は以下の通りです。
- Astro Islands: コンポーネントをアイランドとして分離し、React や Vue など複数のフレームワークを同じプロジェクト内で利用可能。
- Zero JS, by default: ほとんどの JavaScript をビルド時に純粋な HTML に変換し、パフォーマンスを最適化。
詳細な説明については、Astro の公式ドキュメント をご覧ください。
Astro のセットアップ
Astro のセットアッププロセスはスムーズです。以下のステップに従って Astro ブログを開始しましょう。
1. プロジェクトの初期化
以下のコマンドを実行して新しい Astro プロジェクトを作成します。
npm create astro@latest
2. 設定プロンプト
セットアップ中、プロジェクトに関する選択を求められます。以下はその例です。
astro Launch sequence initiated.
dir Where should we create your new project?
./
tmpl How would you like to start your new project?
Use blog template
██████ Template copying...
deps Install dependencies?
Yes
██████ Installing dependencies with npm...
ts Do you plan to write TypeScript?
Yes
use How strict should TypeScript be?
Strict
██████ TypeScript customizing...
git Initialize a new git repository?
Yes
██████ Git initializing...
next Liftoff confirmed. Explore your project!
Run npm run dev to start the dev server. CTRL+C to stop.
Add frameworks like react or tailwind using astro add.
Stuck? Join us at https://astro.build/chat
╭─────╮ Houston:
│ ◠ ◡ ◠ Good luck out there, astronaut! 🚀
╰─────╯
3. 開発サーバーの起動
セットアップが完了したら、以下のコマンドを実行して開発サーバーを起動します。
npm run dev
デフォルトのサーバーは http://localhost:4321/
で利用可能です。
コンテンツコレクション
概要
Astro では、ブログ記事などのコンテンツを コレクション として管理します。詳しくは 公式ページのコンテンツコレクションに関するガイド をご覧ください。
src/content/
配下に任意のディレクトリを作成し、その中に Markdown ファイルを配置します。 MDX もサポートされています。以下はブログ記事のファイル例です (blog/first-post.md
)。
---
title: 'First post'
description: 'Lorem ipsum dolor sit amet'
pubDate: 'Jul 08 2022'
heroImage: '/blog-placeholder-3.jpg'
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
...
コレクションの定義
Astro では、Zod スキーマ検証ライブラリを使って src/content/config.ts
にコレクションのメタデータ (フロントマター) と型を定義できます。この定義は任意ですが、スキーマ検証 や TypeScript タイピング の利点から推奨されます。
The
src/content/config.ts
file is optional. However, choosing not to define your collections will disable some of their best features, like frontmatter schema validation or automatic TypeScript typings.
以下は基本的な config.ts
設定の例です。
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
// Type-check frontmatter using a schema
schema: z.object({
title: z.string(),
description: z.string(),
// Transform string to Date object
pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
heroImage: z.string().optional(),
}),
});
export const collections = { blog };
キー | 型 | 必須 |
---|---|---|
title | string | はい |
description | string | はい |
pubDate | Date | はい |
updatedDate | Date | いいえ |
heroImage | string | いいえ |
コレクションの定義に関する詳細は 公式ガイド をご参照ください。
コレクションの使用方法
Astro では、コンテンツコレクションにアクセスするために getCollection
や getEntry
などの関数を提供しています。
たとえば、フロントマターは data
オブジェクト内に格納されており、簡単にアクセスできます:
---
import { getEntry } from 'astro:content';
const blogPost = await getEntry('blog', 'welcome');
---
<h1>{blogPost.data.title}</h1>
<p>{blogPost.data.description}</p>
コレクションを効果的に定義・活用することで、コンテンツ管理を簡素化し、プロジェクト全体で一貫した構造を維持できます。
ページ
ルーティング
Astro は ファイルベースのルーティング を採用しており、pages
ディレクトリ内のファイルは自動的に特定の URL へマッピングされます。以下にルーティングの例を示します:
ファイル | URL |
---|---|
pages/index.astro | https://<YOUR_DOMAIN>/ |
pages/about.astro | https://<YOUR_DOMAIN>/about/ |
pages/blog/index.astro | https://<YOUR_DOMAIN>/blog/ |
また、動的ルーティング もサポートされています。これは [...NAME]
をディレクトリ名やファイル名として使用することで実現します。たとえば、新規プロジェクトで blog/[...slug].astro
が動的ルーティング用に設定されています。
[...slug]
は次の例のように getStaticPaths
関数内で処理されます:
---
import { type CollectionEntry, getCollection } from 'astro:content';
import BlogPost from '../../layouts/BlogPost.astro';
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map((post) => ({
params: { slug: post.slug },
props: post,
}));
}
type Props = CollectionEntry<'blog'>;
const post = Astro.props;
const { Content } = await post.render();
---
<BlogPost {...post.data}>
<Content />
</BlogPost>
ページ構造
Astro のページ、レイアウト、コンポーネントは、モダンなフロントエンド環境で馴染み深い構造に従います。コンポーネントをページ内に直接配置することもできますが、再利用可能な要素は components
ディレクトリ内に保持することを推奨します。
以下は典型的なページ構造の例です:
src/
├── components/
│ ├── BaseHead.astro
│ ├── Header.astro
│ └── Footer.astro
├── layouts/
│ └── BlogPost.astro
├── pages/
│ ├── index.astro
│ ├── about.astro
│ └── blog/
│ ├── index.astro
│ └── [...slug].astro
Astro コンポーネント
Astro のコンポーネントは React の JSX/TSX に似た構文で記述されます。 React に精通している場合、Astro の構文への移行はスムーズに行えるはずです。以下は pages/index.astro
ファイルのスニペットです:
---
import BaseHead from "../components/BaseHead.astro";
import Header from "../components/Header.astro";
import Footer from "../components/Footer.astro";
import { SITE_TITLE, SITE_DESCRIPTION } from "../consts";
// This will cause an error.
// const main = document.querySelector('main');
---
<!doctype html>
<html lang="en">
<head>
<BaseHead title={SITE_TITLE} description={SITE_DESCRIPTION} />
</head>
<body>
<Header title={SITE_TITLE} />
<main>
<h1>🧑🚀 Hello, Astronaut!</h1>
<!-- Additional content -->
</main>
<Footer />
<script>
// Use document, windoww, etc. here.
const main = document.querySelector('main');
</script>
</body>
</html>
重要な考慮点
Astro のフロントマター(---
ブロック)は Node.js を使用してサーバー上で処理されます。 そのため、document
や window
といったブラウザ固有のオブジェクトはフロントマターでは利用できません。 これらを使用するとエラーが発生します:
error document is not defined
Hint:
Browser APIs are not available on the server.
Move your code to a <script> tag outside of the frontmatter, so the code runs on the client.
See https://docs.astro.build/en/guides/troubleshooting/#document-or-window-is-not-defined for more information.
ブラウザ関連の操作を行う場合は、上述の例のように <script>
タグ内でラップして記述してください。
コンテンツのレンダリング
Astro では、CollectionEntry
から抽出した Content
コンポーネントを使用して、動的にコンテンツをレンダリングできます。以下の例は、pages/blog/[...slug].astro
ファイル内で Content
を使用する方法を示しています:
---
import { type CollectionEntry, getCollection } from 'astro:content';
import BlogPost from '../../layouts/BlogPost.astro';
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map((post) => ({
params: { slug: post.slug },
props: post,
}));
}
type Props = CollectionEntry<'blog'>;
const post = Astro.props;
const { Content } = await post.render();
---
<BlogPost {...post.data}>
<Content />
</BlogPost>
また、Markdown ファイルを直接インポートしてコンポーネントとして利用することも可能です。以下はその例です:
---
import { Content as PromoBanner } from '../components/promoBanner.md';
---
<h2>Today's promo</h2>
<PromoBanner />
Astro は静的および動的ルーティングを組み合わせた柔軟なアプローチを採用しており、直感的なレンダリングプロセスとコンポーネントシステムが特徴です。これにより、スケーラブルで高性能なウェブサイトを構築するための強力なツールとなっています。
ビルド
npm run build
または astro build
を実行することで、ビルドアーティファクトが dist/
ディレクトリに生成されます。これらのアーティファクトは完全にビルドされたサイトを表しており、デプロイの準備が整っています。以下は、セットアップ直後の生成出力例です:
ビルド後には、JavaScript は一切生成されません。これにより、ビルドは軽量かつ高効率になります。
ビルド出力の例
tree dist/ --dirsfirst
dist/
├── about
│ └── index.html
├── blog
│ ├── first-post
│ │ └── index.html
│ ├── markdown-style-guide
│ │ └── index.html
│ ├── second-post
│ │ └── index.html
│ ├── third-post
│ │ └── index.html
│ ├── using-mdx
│ │ └── index.html
│ └── index.html
├── fonts
│ ├── atkinson-bold.woff
│ └── atkinson-regular.woff
├── blog-placeholder-1.jpg
├── blog-placeholder-2.jpg
├── blog-placeholder-3.jpg
├── blog-placeholder-4.jpg
├── blog-placeholder-5.jpg
├── blog-placeholder-about.jpg
├── favicon.svg
├── index.html
├── rss.xml
├── sitemap-0.xml
└── sitemap-index.xml
重要なポイント
- HTML 出力: すべてのページが静的な HTML ファイルとして事前にレンダリングされます。
- JavaScript 非生成: Astro は、フレームワークやコンポーネントを通じて明示的に追加されない限り、JavaScript を生成しません。
- 静的アセット: フォントや画像などの静的リソースはそのまま含まれ、不必要な処理が防止されます。
Astro のビルドプロセスは、スピード と 効率性 を重視して設計されており、パフォーマンスを最優先とするウェブサイトに最適です。
その他のトピック
Image コンポーネント
Astro は、最適化された画像処理のための Image
コンポーネントを提供します。src/
ディレクトリに配置された画像は、ビルドプロセス中に変換され、WebP フォーマットに最適化されます。これにより、パフォーマンスが向上します。
推奨事項
- 画像の最適化が必要な場合は、
src/
ディレクトリに配置します。 - 変換が必要なローカル画像は
public/
ディレクトリを使用せず、src/
ディレクトリに配置してください。
詳細については、Astro Images Guide をご参照ください。
Tailwind CSS の統合
Astro は Tailwind CSS を統合システムを通じてサポートしています。 Tailwind をインストールするには、以下を実行してください:
npx astro add tailwind
このプロセスでは以下を行います:
@astrojs/tailwind
と必要なtailwindcss
パッケージをインストールします。- 最小限の設定を持つ
tailwind.config.mjs
ファイルを生成します。 astro.config.mjs
ファイルのintegrations
配列に Tailwind を追加します。
Tailwind の使用例
<body>
<Header />
<main class="ml-2">
<!-- コンテンツをここに追加 -->
</main>
<Footer />
</body>
詳細については、Tailwind Integration Guide をご覧ください。
IDE サポート
Astro は、開発体験を向上させるために IDE プラグインを提供しています。
IDE | 提供元 | 安定性 |
---|---|---|
VS Code | Astro | 安定版 |
JetBrains | JetBrains | 2023年11月時点で不安定な印象 |
これらのプラグインを活用することで、構文ハイライト、IntelliSense、自動補完、エラー検出が可能になります。
まとめ
Astro は、パフォーマンス、シンプルさ、開発者向けツールを重視することで、静的ウェブサイト構築の体験を楽しく効率的なものにしています。Astro Islands や Zero JS by default などの機能により、モダンな静的サイトジェネレーターとして高い注目を集めています。
この記事が、次回のプロジェクトで Astro を試してみるきっかけになれば幸いです。
Happy Coding! 🚀