📑

Astro v2 と Cloudflare Pages で Markdown をレンダリングするサイトを独自ドメインでデプロイする

2023/03/17に公開

最近では個人的なブログを自作するハードルは限りなく下がりました。静的サイトジェネレーターの Gatsby や Hugo を使うことで簡単にブログなどの Web サイトを作成できます。

最近、Astro という静的サイトジェネレーターが巷で流行っていると聞いたので試してみました。最近はホスティングもほとんど自動で行ってくれる便利なものがたくさんあるのでそれにあやかります。今回は Cloudflare Pages を使いました。Cloudflare Domain で取得し Pages に紐づけることで簡単に独自ドメインで公開もできるので便利です。

前提

Cloudflare のアカウントを作成し、Cloudflare Pages を使えるようにしておきます。デプロイと公開は無料でできます。ドメイン取得には取得するドメインに応じて料金がかかります。

Astro とは

Astro とは、静的サイトジェネレーターの一種です。特徴は、Zero Runtime JavaScript です。Static Generation 時にサーバーサイドで不要な JavaScript を削除してから HTML を生成します。そのため、ブラウザが受け取るのは HTML と CSS のみとなるため高速に動作するようです。

また、Astro Islands という仕組みでコンポーネントごとに別のフレームワークを選択できます。Integration という仕組みがあり特定の UI フレームワークに依存しないため、好きなフレームワークを使うことができます。各コンポーネントが独立しているため極端な話ヘッダーコンポーネントは React、コンテンツは Vue.js を使うということもできます。

公式でも言及されていますが、Astro は Web アプリケーションではなく、コンテンツベースの Web サイトを作るフレームワークと強調されています。Web アプリケーションを作る場合は Next.js、静的なサイトを作る場合は Astro を使うなど他のフレームワークと棲み分ければ良さそうですね。

作ってみた

Getting Started

基本的には公式のGetting Startedを参照してプロジェクトの雛形を作成します。この記事では詳しく手順は書きません。

markdownをContent Collectionsで管理する

Astro 2.0 から Content Collections という機能が追加されました。/src/content 配下に置くことで Markdown をコンテンツの種類ごとに管理できます。さらに zod を使うことで、markdown のヘッダーのバリデーションや Type safe で扱うことができるようになりました。astro からは /content 配下にアクセスするための専用の API が用意されているので、それ経由で markdown を一括で取得したり個別で取得します。

markdownをHTMLに変換する

markdown を書いてそのままビルドしてもそのままの文字列が出てしまうので、markdown を HTML に変換する仕組みが必要になります。zenn-markdown-html という Zenn が OSS で提供している markdown のパーサがあるのでそれを使います。

https://github.com/zenn-dev/zenn-editor

必要なライブラリをインストールします。

npm install zenn-content-css zenn-embed-elements zenn-markdown-html

tsx を使いたいので、Astro 上で React を使用できるようにします。Astro は Integration という仕組みで、すぐに UI フレームワークを導入できるようになっているのでそれを利用します。

npx astro add react

以下のように、/src/components/Article.tsx を作成し、markdown のコンテンツを受け取って、HTML に変換してレンダリングするコンポーネントを作成します。

import { useEffect } from "react";
import markdownToHtml from 'zenn-markdown-html';
import "zenn-content-css";

type Props = {
  body: string;
};

export const Article = (props: Props): JSX.Element => {
  const { body } = props;
  const html = markdownToHtml(body);

  useEffect(() => {
    import("zenn-embed-elements");
  }, []);

  return (
    <div
      className="znc"
      dangerouslySetInnerHTML={{
        __html: html,
      }}
    />
  );
};

このコンポーネントを Astro のページから使用します。pages/articles/[slug].astro にダイナミックルーティングのファイルを作成します。getCollection を使うことで /content 配下にある markdown の一覧を取得できます。getStaticPaths 関数でダイナミックルーティングの SSG を行います。

---
import { getCollection } from "astro:content";

import { Article } from "../../components/Article";
import Layout from "../../layouts/BaseLayout.astro";

export async function getStaticPaths() {
  const articleEntries = await getCollection("article");

  return articleEntries.map((entry) => {
    return {
      params: {
        slug: entry.slug,
      },
      props: {
        title: entry.data.title,
        tags: entry.data.tags,
        body: entry.body,
      },
    };
  });
}

const { body, title, tags } = Astro.props;
---

<Layout title="hoge">
  <main>
    <h1>{title}</h1>
    <Article body={body} />
  </main>
</Layout>

これで markdown ファイルを増やすごとに自動的に新しい記事ページができあがるようになります。

Cloudflare Pages にデプロイする

Astro は Cloudflare Pages では、SSG、SSR 両方に対応しています。今回は SSG でデプロイします。SSG はデフォルトの動作なのでとくに設定をする必要はないです。

デプロイ

GitHub にリポジトリを作成し Astro のプロジェクトを Push しておきます。

Cloudflare のコンソールにアクセスし Create Project > Connect to Git を選択します。Select a repository で作成したリポジトリを指定し Begin setup します。

Project Name に適当な名前を入れて Production branch にデプロイ対象のブランチを入力します。自動で Astro を認識し Framework preset に Astro が表示されていると思います。表示されていなかったら Astro を選択します。Build Command と Build output directory はそのままで OK です。Save and Deploy を押してちょっと待てばデプロイが完了です。めちゃくちゃ簡単です。

独自ドメインで公開する

Cloudflare では DNS 機能があるので独自ドメインで公開できます。またレジストラーでもあるのでドメインを取得できます。今回は、ドメインを購入し DNS に設定してみます。

Domain Registration > Register Domains を選択肢取得したいドメイン名を入力します。入力して検索すると取得できるドメインの一覧が出てくるので、選択して購入します。購入はクレジットカードか Paypal を選択できました。

取得できたら、Pages に移動して、プロジェクトを選択します。Custom domains タブを選択し Set up a custom domain でさきほど取得したドメイン名を入力します。サブドメインで公開する場合はサブドメインを入力します。

Begin DNS transfer を押して、サイトの作成画面に遷移します。公開するドメイン名を入力します。

作成したサイトのコンソールに移動し DNS > Records を開いて CNAME レコードを設定します。Name には公開するドメインを入力します。Target は Pages の Deployment のドメインを設定します。

しばらくすると習得したドメインでサイトにアクセスできると思います。

まとめ

Astro でブログサイトを作ってみました。SPA の機能はないので、Web アプリケーションを作るのは他のフレームワークのほうが向いていそうですが、コンテンツベースの Web 制作などには強力なフレームワークだと感じました。HTML と CSS のみでコンポーネントを作成でき、UI フレームワークを使いたかったらその都度コンポーネントごとに使えばいいという特定のフレームワークに依存しないのも良いと思いました。また、必要に応じて Headless CMS や DB との連携もできるので拡張性もありそうです。

GitHubで編集を提案

Discussion