このブログの技術スタック

| #astro#tailwindcss#cloudflare#mdx

シリーズ: ブログ構築

概要

このブログは 完全な静的サイト として構築されています。JavaScript をほぼゼロにし、表示速度と SEO を最優先にした設計です。

主な技術スタックは以下の通りです。

カテゴリ技術
フレームワークAstro v5
コンテンツMDX
スタイリングTailwind CSS v4 + Typography
コードハイライトShiki
ホスティングCloudflare Pages
パッケージマネージャpnpm
CIGitHub 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

構造化データ

各記事ページには BlogPostingBreadcrumbList の JSON-LD を埋め込んでいます。Google の検索結果にリッチリザルトが表示されることを狙った対応です。

メタタグ

全ページに以下を設定しています。

  • canonical URL
  • Open Graph (og:title, og:description, og:image 等)
  • Twitter Card (summary_large_image)
  • article:published_time / article:modified_time

sitemap / RSS / robots.txt

@astrojs/sitemapsitemap-index.xml を自動生成し、@astrojs/rss/rss.xml を生成しています。robots.txtpublic/ に静的配置です。

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 秒以下です。


関連記事