Next.js vs. Astro: Markdown ブログ構築の勝者は?開発体験に基づく徹底比較!

Next.js vs. Astro: Markdown ブログ構築の勝者は?開発体験に基づく徹底比較!

Next.js vs. Astro: Markdown ブログ構築の勝者は?開発体験に基づく徹底比較!

はじめに:Next.jsからのAstroへの移行劇

約6ヶ月前、私は自身のウェブサイトをGatsby.jsからNext.jsに移行しようと試みました。Next.jsの大ファンだったからです。しかし、何時間も無駄な時間を費やした後、Next.jsは私の個人的なウェブサイトにとって最適なフレームワークではないことに気づきました。そこで、私はAstroへの移行を決断しました。

この記事では、Next.jsでの苦労と、Astroが特定のタイプのウェブサイト(特にMarkdownブログ)の作成を驚くほど容易にした素晴らしい機能についてご紹介します。

Next.jsでの苦労:Markdownブログ構築の壁

Next.jsは私のお気に入りのフレームワークの一つであり、多くのデモで使用しています(このチャンネルでもよく見かけるでしょう)。この記事はNext.jsを批判するものではありません。Next.jsの限界というよりは、特定のタイプのウェブサイトを作成する際の開発者体験における課題に焦点を当てています。

私の個人的なウェブサイトは、フルスタックの機能は多くありません。主にブログ投稿と講演に関する情報(Markdown形式で埋め込まれた情報)です。以前は、Sanity.ioをヘッドレスCMSとして使用していましたが、コンテンツをソースコードに移動して、直接編集したり、他の人がPRで修正したりできるようにしたいと考えました。

そこで、GatsbyからNext.jsへの移行を開始しました。しかし、いくつかの問題に直面しました。

  • Markdownファイルの読み込み: カスタムJavaScriptを記述する必要がありました。ファイルシステムAPIを使用して、Markdownファイルを手動で処理し、必要な情報を抽出する必要がありました。これは非常に手動的なプロセスであり、ブログ投稿作成者にとって一般的な作業なのに、自動化ツールがないのが問題でした。後述するAstroでの同等の処理と比較してみてください。
// Next.jsでのMarkdownファイル処理の例(簡略化)
const fs = require('fs');
const path = require('path');
const matter = require('gray-matter'); // Frontmatter解析用パッケージ

const files = fs.readdirSync(path.join(__dirname, 'posts'));
const posts = files.map((file) => {
  const slug = file.replace('.md', '');
  const markdownWithMeta = fs.readFileSync(path.join(__dirname, 'posts', file), 'utf-8');
  const { data, content } = matter(markdownWithMeta);
  return { slug, ...data, content };
});
  • フロントマターの処理: 特定の新しいパッケージ(gray-matterなど)を導入して、Markdownファイルからフロントマター(メタデータ)を取得する必要がありました。
---
title: "AstroのMarkdownブログ構築体験"
date: "2024-12-31"
description: "Next.jsとAstroを比較したブログ構築体験を紹介します。"
---
  • Markdownレンダリング: react-markdownのような追加パッケージをインストールして設定する必要がありました。シンタックスハイライト(Prismなど)の設定も複雑で、画像やコードの処理に多くの時間を費やしました。これは、すぐにカオス状態に陥る可能性があります。

  • コンテンツの構造の理解: フロントマターにどのようなコンテンツを入れるべきか理解するのも難しい点でした。これは、Astroのコンテンツコレクション機能で解決できるポイントです。

要約すると、Next.jsは非常に強力なフレームワークですが、埋め込みMarkdownの処理とレンダリングに関して、想定以上に多くの作業が必要でした。

Astro: Markdown ブログ構築の革命

そこで、Astroを試してみることにしました。驚くべきことに、1、2日以内にウェブサイト全体をAstroに移行することができました。その理由は、Astroのいくつかの素晴らしい機能にあります。

1. コンテンツコレクション:Markdownの楽園

Astroの最も重要な機能の一つは、コンテンツコレクションです。astro.config.mjsファイル内のconfigオブジェクトで、MarkdownやMDXファイルなどのデータコレクションを定義できます。

// astro.config.mjs の例
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import mdx from '@astrojs/mdx';

export default defineConfig({
  integrations: [react(), mdx()],
  content: {
    source: './content', // コンテンツディレクトリ
    // 以下にコレクションを定義
    collection: {
      type: 'content',
      schema: ({ default: {} }) => ({
        title: { type: 'string', required: true },
        date: { type: 'string', required: true },
        description: { type: 'string' },
      }),
    },
    blog: {
        type: 'content',
        schema: ({ default: {} }) => ({
            title: { type: 'string', required: true },
            date: { type: 'string', required: true },
            description: { type: 'string' },
            coverImage: { type: 'string' },
            tags: { type: 'string[]' },
            youtubeVideoID: { type: 'string' },
        }),
    }
  },
});

Astroは、Markdownをそのままサポートします。pagesディレクトリにindex.mdファイルを作成するだけで、ページとして認識されます。追加の設定はほとんど必要ありません。MDXも同様に容易にサポートしています。

2. 型安全なデータアクセス:IntelliSenseの恩恵

コンテンツコレクションを定義することで、型安全なデータアクセスが可能になります。これにより、開発者ツールのIntelliSenseが強力なサポートを提供し、コードの記述ミスを減らすことができます。

私の作成したユーティリティファイルでは、ファイルディレクトリやファイルシステムを手動でクエリする必要がありません。AstroのgetCollecion()関数を使用するだけで、指定したコレクションのデータを取得できます。

// Astro でのコンテンツ取得の例
import { getCollection } from 'astro:content';

const posts = await getCollection('blog');

これにより、型安全なデータ(posts[0].titleなど)にアクセスできるようになり、開発効率が向上します。

3. 組み込みページネーション:シンプルで強力

Astroは、ページネーション機能も組み込みで提供しています。getCollecion()関数の返り値にページネーション機能を適用することで、複数のページにまたがるコンテンツを簡単に表示できます。

Next.jsでは、この機能を手作業で構築する必要がありましたが、Astroでは、静的なパスとページサイズを渡すだけで簡単に実現できます。これは開発時間の大幅な節約につながります。

4. 組み込みシンタックスハイライト:美しいコード表示

Astroは、Markdownファイル内のコードブロックに対して、シンタックスハイライトを自動的に適用します。私は、追加のスタイリングをほとんど行わずに、見栄えの良いコードブロックを実現することができました。

5. 動的なルートとページネーション:スムーズなナビゲーション

動的なルート(/[slug].astro)を使用することで、個々のブログ投稿を簡単に表示できます。ページネーションコンポーネントでは、pageオブジェクトを使用して、前後のページへのリンクを動的に生成できます。

Astroによる完成されたブログ:実例

Astroを用いたブログは、以下のようにレンダリングされます。Tailwind CSSによるスタイリングと、組み込みのシンタックスハイライトが利用されています。

(画像:レンダリングされたブログ投稿のスクリーンショット)

ページネーションも問題なく機能します。URLに/1, /2などページ番号が含まれていることを確認できます。

(画像:ページネーションのスクリーンショット)

Astroの限界と補足事項

Astroは静的サイトジェネレーターとして設計されていますが、APIエンドポイントを使用した動的な機能も追加できます。私のニュースレターの送信フォームや、ニュースレターコンテンツの生成APIなどは、AstroのAPIエンドポイントを使用して実装されています。これは、Astroが静的サイトだけに限定されないことを示しています。

Astroコースのご紹介

Astroに興味があり、Astroを用いたモダンなウェブサイトの構築を学びたい方は、私のコース Astro Course (astrocourse.dev) をご確認ください。このコースでは、基本的なブログから、コメント機能、認証、自動生成カバー画像など高度な機能まで、段階的に学習できます。夏にローンチ予定です!ニュースレターに登録すると、25%のローンチ割引を受けられます。

まとめ:AstroでMarkdownブログをもっと簡単に!

Next.jsとAstroを用いたMarkdownブログ構築を比較した結果、Astroは、そのコンテンツコレクション型安全なデータアクセス組み込みページネーションシンタックスハイライトといった機能により、開発者体験を飛躍的に向上させました。特にMarkdownブログのような静的コンテンツ中心のウェブサイトでは、Astroが圧倒的に効率的です。

あなたの個人的なウェブサイトでどのフレームワークを使用していますか?Astroに興味がありますか?ぜひコメント欄で教えてください!

(リンク:Astro Course (astrocourse.dev))

(リンク:YouTubeチャンネル)