このブログの技術スタック
シリーズ: ブログ構築
概要
このブログは 完全な静的サイト として構築されています。JavaScript をほぼゼロにし、表示速度と SEO を最優先にした設計です。
主な技術スタックは以下の通りです。
| カテゴリ | 技術 |
|---|---|
| フレームワーク | Astro v5 |
| コンテンツ | MDX |
| スタイリング | Tailwind CSS v4 + Typography |
| コードハイライト | Shiki |
| ホスティング | Cloudflare Pages |
| パッケージマネージャ | pnpm |
| CI | GitHub Actions |
Astro
Astro はコンテンツ駆動の Web サイトに最適化されたフレームワークです。
採用した理由はシンプルで、ブログに不要な JavaScript を一切送らないからです。React や Vue のランタイムを含まず、ビルド時に HTML を生成するだけなので圧倒的に軽量です。
Content Collections
Astro の Content Collections を使い、frontmatter を Zod スキーマで型安全に管理しています。
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
const posts = defineCollection({
loader: glob({ pattern: '**/*.mdx', base: './src/content/posts' }),
schema: z.object({
title: z.string(),
description: z.string(),
publishedAt: z.coerce.date(),
updatedAt: z.coerce.date(),
tags: z.array(z.string()),
series: z.string().optional(),
draft: z.boolean().optional().default(false),
}),
});
z.coerce.date() を使うことで、frontmatter に 2025-01-27 のような文字列を書いても自動的に Date オブジェクトに変換されます。型が合わなければビルド時にエラーになるため、記事のメタデータが壊れる心配がありません。
MDX
記事は MDX で書いています。Markdown の中に JSX コンポーネントを埋め込めるので、将来的にインタラクティブな要素を追加する余地を残しています。
現時点では純粋な Markdown としてしか使っていませんが、MDX を選んだのはあくまで拡張性のためです。
Tailwind CSS v4
スタイリングには Tailwind CSS v4 を使っています。v4 では @tailwindcss/vite プラグインで Astro の Vite に直接統合できます。
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
vite: {
plugins: [tailwindcss()],
},
});
カラースキーム: Cobalt Night
配色は Cobalt Night というカスタムテーマを使っています。Tailwind v4 の @theme ディレクティブで CSS 変数を定義し、サイト全体で参照しています。
@theme {
--color-bg: #070a12;
--color-surface: #0c1020;
--color-surface2: #0e1630;
--color-text: #e8eef9;
--color-muted: #a9b4cb;
--color-accent: #2f7dff;
--color-accent2: #67a5ff;
--color-border: #1c2a55;
--color-code-bg: #050816;
}
これにより、Tailwind のユーティリティクラスで bg-bg, text-accent, border-border のように直接使えます。
Typography プラグイン
記事本文のタイポグラフィは @tailwindcss/typography に任せています。prose クラスを当てるだけで、見出し・段落・リスト・コードブロックなどが整います。ダークテーマに合わせて prose の CSS 変数を全てオーバーライドしています。
Shiki によるコードハイライト
Astro に組み込みの Shiki をそのまま使っています。テーマは github-dark を採用し、Cobalt Night の背景色に合わせて CSS で上書きしています。
ファイル名タブ
コードブロックに title メタを指定すると、ファイル名がタブ風に表示されます。Shiki の transformer で data-title 属性を注入し、CSS の ::before 擬似要素で描画しています。
transformers: [
{
name: "title",
pre(node) {
const title = this.options.meta?.__raw?.match(
/title="([^"]+)"/
)?.[1];
if (!title) return;
node.properties["data-title"] = title;
},
},
],
コピーボタン
コードブロックにはホバーでコピーボタンが表示されます。クライアントサイドの JavaScript で pre 要素にボタンを注入し、navigator.clipboard API でコピーを実行します。Astro の SSG と相性を保つため、<script> タグで軽量に実装しています。
SEO
構造化データ
各記事ページには BlogPosting と BreadcrumbList の JSON-LD を埋め込んでいます。Google の検索結果にリッチリザルトが表示されることを狙った対応です。
メタタグ
全ページに以下を設定しています。
canonicalURL- Open Graph (
og:title,og:description,og:image等) - Twitter Card (
summary_large_image) article:published_time/article:modified_time
sitemap / RSS / robots.txt
@astrojs/sitemap で sitemap-index.xml を自動生成し、@astrojs/rss で /rss.xml を生成しています。robots.txt は public/ に静的配置です。
Cloudflare Pages
ホスティングは Cloudflare Pages を使っています。GitHub リポジトリと連携し、main ブランチへの push でビルド・デプロイが自動実行されます。
ビルドコマンドは pnpm build のみで、dist/ ディレクトリがそのまま配信されます。
www.takagiakihiro.dev から takagiakihiro.dev への 301 リダイレクトは public/_redirects で設定しています。
https://www.takagiakihiro.dev/* https://takagiakihiro.dev/:splat 301
CI
GitHub Actions で main ブランチへの push と Pull Request に対してビルドチェックを実行しています。
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm build
まとめ
技術選定の方針は「シンプルに、速く、壊れにくく」です。
- Astro で JS ゼロの静的 HTML を生成
- MDX でコンテンツを管理し、型安全な frontmatter で品質を担保
- Tailwind CSS v4 で CSS 変数ベースのデザインシステムを構築
- Shiki でビルド時にシンタックスハイライトを完結
- Cloudflare Pages で高速に配信
依存パッケージは最小限に抑えており、ビルド時間は 2 秒以下です。