ブログサイトをモダンで高速なAstroで制作したらとても快適だった

ブログサイトをモダンで高速なAstroで制作しました。Webサイトの開発環境が簡単に構築できて、ビルド後も高速に動作するのでおすすめのフレームワークです。
リメディアのブログサイトを制作する際に、Astroというフレームワークを採用しました。Webサイトの開発環境を簡単に構築できるので、とくにWeb制作を行っているデザイナーやエンジニアにはオススメです!この記事ではそのAstroについて解説します。
Astroとは
Astroは静的なWebコンテンツを生成するための静的サイトジェネレーターです。2021年に登場し、2022年8月に正式リリースされましたが、それ以降も活発的に開発が続けられています。とくに最近では、Webサイトの制作者にとても人気のツールとして話題に上がることが多いです。
静的サイトジェネレーターについて
静的サイトジェネレーター (Static Site Generator = SSG) は、入力したデータファイルから静的ページ(HTML/CSS/JavaScript)を出力するツールで、Webサイトの表示パフォーマンスを高速化できます。
WordPressのようなCMSはサーバー上のデータベースを元にHTMLを生成して返すものですが、静的サイトジェネレーターは、事前に生成されたHTMLを配信することでサイトの表示を高速にできるメリットがあります。
Astroを選んだ理由
Webサイト制作をメインにしていると、ReactやNext.jsなどのフレームワークを使うのは難しいと感じる制作者も多いと思います。実際にそれらはWebアプリケーション開発でよく使われており、静的なサイトの生成が必要なだけであれば、少々オーバースペックになってしまいます。
そこでAstroです!もちろんメリットもあればデメリットもありますが、それらを比較しても使ってみる価値は十分にあると思います。
Astroのメリット
- パフォーマンス重視でJavaScriptは最低限
- シンプルな記述でサイトを生成でき、デザイナー(非エンジニア)でも扱いやすい
- 公式ドキュメントサイトが日本語にも対応
Astroのデメリット
- コンポーネントを用いた開発手法が、他のJSフレームワークに触れてないとすこし分かりづらい
- 独自の
*.astro
というファイルを使用する必要がある - 新しいフレームワークなので進化が早く、仕様が変わりやすい
Astroはページの生成時(ビルド時)になるべくJavaScriptを削除したうえで、HTMLとCSSを生成します。不要なJavaScriptを削除することによって、Webサイトの表示パフォーマンスを最適化できます。
実際に、このブログサイトはJavaScriptが無効な環境でも(一部無効になる機能はありますが)高速に動作します。そもそも、あまりJavaScriptを使用した機能がないという前提ではあります。
いざ導入してみる
導入するための事前の懸念点などは、上記で検討したとおり大きな問題はなさそうでしたので、実際に進めてみます。まずは触ってみることが一番なので公式のチュートリアルから始めてみました。

このチュートリアルをすべて進めたうえで「これはいける!」と思いましたが、いくつか落とし穴がありました。
このチュートリアルでは最新のAstroのバージョンに対応していないようで、とくに今回使用することの多いMarkdownファイルでのコンテンツ管理の機能「コンテンツコレクション(Content Collections)」に非対応の内容となっていました。
Content CollectionsはAstro 2.0から導入されたコンテンツ管理のための機能ですが、チュートリアル対応後に知ったので、結果的にそれらに関する記述を書き換える必要がありました…。ただ、そこまで大変でもなかったのと、コンテンツ管理もより柔軟になったので結果的に対応してよかったです。
他にも色々と書き換える部分は多くありましたが、とても良くできてるチュートリアルなので、これから始めてみる方にはオススメです。
制作時に困ったことなど
進めていく中でいくつか困ったことなどがあったのでご紹介します。基本的にググればある程度の解決はできましたので、Astroについての情報を発信している方にはとても感謝しています。
サブディレクトリにページをbuildしたい
このブログサイトではドメイン直下の/blog/
ディレクトリにページを生成したいので、以下のようにbaseを設定することで解決できました。同じようなことを考えている方は多いようで、Web上に情報が多かったので助かりました。
// astro.config.mjs
const subfolder = '/blog/'
export default defineConfig({
base: subfolder,
outDir: `./dist${subfolder}`,
});
これで生成後のファイルがhttps://www.remedia.co.jp/blog/
以下に配置されるようになります。
投稿データをJSON化したい
このブログサイト以外からも記事の投稿データを取得するようにしたいと考えていました。例えば当社のコーポレートサイトはブログサイトとは別で制作されているので、JSONなどでデータを取得してブログ投稿をサイトに表示できると便利そうです。
しかしAstroの標準機能ではそういった仕組みはないので、以下のようなpost.json.ts
ファイルで投稿データをJSON化して書き出す手法を採用しました。
// src/pages/data/post.json.ts
import { getCollection } from "astro:content";
import { format, compareDesc } from "date-fns";
import { tagsData } from "@lib/constants";
export async function GET() {
// すべての投稿データを取得 公開日のソートなども対応
const allPosts = await getCollection("posts");
allPosts.sort((a, b) => compareDesc(a.data.pubDate, b.data.pubDate));
const body = allPosts.map((post) => {
const tags = post.data.tags.map((tagSlug) => {
return tagsData.find((t) => t.tagSlug === tagSlug).tagName;
});
// タイトルやディスクリプションなどの情報を生成
return {
title: post.data.title,
description: post.data.description,
slug: post.slug,
image: post.data.image,
pubDate: format(post.data.pubDate, "yyyy/MM/dd"),
tags,
};
});
// JSON レスポンスを返却(UTF-8への変換も行う)
return new Response(JSON.stringify(body), {
status: 200,
headers: { "Content-Type": "application/json; charset=utf-8" },
});
}
これで返ってくるJSONの一部が以下のようなものになります。
// post.json
{
"title": "ブログサイトをモダンで高速なAstroで制作したらとても快適だった",
"description": "ブログサイトをモダンで高速なAstroで制作しました。Webサイトの開発環境が簡単に構築できて、ビルド後も高速に動作するのでおすすめのフレームワークです。",
"slug": "2023-04-astro-blog",
}
以前は.astro
ファイルで投稿データをJSON化して、ページとして書き出す手法を採用しました。書き出されるデータはあくまでHTMLファイルなので、取得できたJSONデータはまた別の.json
ファイルとして用意する必要がありました。
正直面倒ではありますが、他にいい方法が見つからなかったのでこのようにしいています。
↑のようなコメントを入れてましたが、より効率的な方法が見つかってよかったです!
ビルド後には/blog/data/post.json
にアクセスすると、そのままJSONファイルとして書き出されます。これで、記事の投稿データを他のページからデータを取得できるようになりました。
タグ名を日本語でなく英語にしたい
例えば「マーケティング」というタグを用意したときに、/tag/マーケティング/
でなく/tag/marketing/
といったように英数字でのURLにしたいと思いました。
もう少し細かく言えば「Webサイトに表示されるタグの文字」と「ブラウザのURLバーに表示される文字」を別のものとして管理したかったのです。なかなかいい方法が見つからない中、目にとまったのが以下の電子書籍です。

こちらで紹介されている方法では、タグの設定を外部ファイル化して、タグの名前とID名(スラッグ)を別で管理するようになっていました。
export const tagsData = [
{ tagName: "HTML", tagSlug: "html" },
{ tagName: "マーケティング", tagSlug: "marketing" },
];
この方法であれば、サイト上に表示されるタグ名は「マーケティング」であっても、ブラウザのURLバーに表示される文字は「marketing」となるので、スッキリしました。
非公開記事を設定したい
まだ公開したくない記事や、テンプレート的に使う記事ファイルもあるかもしれません。Gitでそれらを管理しながら、公開環境には反映しない設定もしました。
まずは対象となる記事ファイルのフロントマターに draft: true
を追加します。
---
title: "記事タイトル"
pubDate: "2025-07-02"
draft: true # こちらを追加
---
続いて記事の一覧ページでdraft
を除外します。
const allPosts = await getCollection("posts", ({ data }) =>
import.meta.env.PROD ? !data.draft : true
);
これで、一覧ページからは非表示となるのですが、対象ページのSlugを入力したURLにアクセスするとページとして表示されてしまいます。src/pages/posts/[slug].astro
のように、スラッグを基準にページを生成する場合は、ページ自体の生成は避けられないようです。
そこで、以下のように対象ページにアクセスすると404を返すようになり、意図しないページの公開を避けることができます。
if (import.meta.env.PROD && post.data.draft) {
throw new Error("404");
}
以上、ちょっと説明やコードが長くなりましたが、こんな感じでブログサイトの構築が完了しました!これからも機能のアップデートや改善を行いながら、その情報を共有していこうと思います。
公開後のあれこれ
パフォーマンス測定
PageSpeed Insightsで測定すると、デスクトップ版で以下のスコアになりました。
パフォーマンス | ユーザー補助 | おすすめの方法 | SEO |
---|---|---|---|
93 | 100 | 100 | 100 |
もう少しで満点!でしたが、パフォーマンスがわずかに届かず。以下がスコアを下げる要因でしたが、こちらは簡単に外せないので許容範囲とします。
- サードパーティのJavaScriptファイル(計測用のタグなど)
- Webフォントの読み込み
Webフォントの読み込みについては改善が可能か、引き続き検討していこうと思います。
Astro 4.0のリリース!
12月5日にAstro 4.0がリリースされました。Astro 3.0からアップグレードして、とくに問題なかったのでそのまま更新してみました。まだ新機能をすべて確認できていませんが、ビルドは明らかに早くなってます!
あと、Devツールバーが便利そうですね。アクセシビリティチェックなどの検査ツールが開発画面上に出てくるので、使いこなしていきたいです。
はやすぎて色々追いつくのが大変ですが、今後も新機能の紹介などをしていきます。
さいごに
このサイトの技術的な背景をまとめてみましたが、いくつかご紹介できなかったものもあります。
- ダークモード対応
- TailwindCSSの導入
- Gitと連携したデプロイの自動化
ただ、これらはAstroに関連しないものも多いので、また別の機会にご紹介しようと思います。
Astroでのサイト構築を中心に色々とご紹介してきましたが、このブログサイトは技術的な実験の場としても活用します。そのうえで、共有できることがあれば積極的に記事にしていきたいと思っています!