このサイトは Astro 5 + Tailwind CSS v4 + Cloudflare Pages で作っています。普段の仕事では Next.js を使うことが多いのですが、このサイトに限っては Astro を選びました。その理由を書きます。
Next.js ではなく Astro にした理由
一番の理由は、このサイトに動的な要素がほとんどないことです。プロフィール、作ったものの一覧、記事。どれもビルド時に確定します。
Next.js でも静的書き出しはできますが、Astro は「デフォルトでJSを送らない」設計です。インタラクションが必要な箇所だけを島(Island)として切り出す発想なので、何もしなければ本当に何も送られません。結果としてスマホでの初回表示が速くなります。
ポートフォリオサイトはそれ自体が実力の展示物でもあります。開いた瞬間に速いことが、説明よりも雄弁だと考えました。
構成
- Astro 5 — 静的生成。Content Collections で記事とプロダクトを型付き管理
- Tailwind CSS v4 —
@theme inlineでデザイントークンをCSS変数に橋渡し - Cloudflare Pages — ホスティング。問い合わせフォームは Pages Functions で受ける
- Cloudflare Web Analytics — Cookie を使わないので同意バナーが要らない
記事とプロダクトを同じ仕組みで扱う
Content Collections で blog と products の2つを定義しています。プロダクト情報を Markdown の frontmatter に持たせることで、記事と同じ書き味で編集でき、スキーマ違反はビルド時に落ちます。
const products = defineCollection({
loader: glob({ base: "./src/content/products", pattern: "**/*.md" }),
schema: z.object({
title: z.string(),
summary: z.string(),
stack: z.array(z.string()),
demoUrl: z.string().url().optional(),
}),
})
demoUrl を .optional() にしてあるのは、公開URLがまだ無いプロダクトがあるためです。空文字を入れて空リンクを出すより、プロパティごと省略してボタンを出さないほうがいい。
これから
まずは公開して、記事と実績を足しながら育てていきます。デザインを詰めきる前に出すと決めていました。完成を待っていると、いつまでも公開されないので。
このサイトのように「速くて運用しやすいサイトが欲しい」というご相談も受け付けています。お問い合わせからお気軽にどうぞ。