Skip to content

Astro+Cloudflare Pagesでブログ構築

Posted on:2023年10月31日
Post tags:

久しぶりにブログを書こうと思い立って、Astro + Cloudflare Pages でブログサイトを作った。この手の静的サイトジェネレーターだと Hugo、Gatsby、Jekyll あたりが有名だけど、どうせなら触ったことのない新しいものの方がよいと思って Astro にした。最初、何も分からないところからスタートしたのだけれど、結果として Astro はブログのようなサイトを作るのに最適でとても気に入ってしまった。

Astroの特徴でいいなと思ったのはこのあたり。

公式サイトに掲載されている比較のグラフ: Astro Performance

Astro 公式のチュートリアルで概要を把握

Astro についての基本を学ぶために、まず公式サイトのチュートリアルをやってみた。そのものずばりなブログサイトを構築するというチュートリアルが用意されていて、これを最後までやったら開発方法の概要が理解できた。

初めてのAstroブログ 🚀 Astroドキュメント Astro Tutorial

大体2〜3時間あれば終えられる内容なので、ブログサイトを作るつもりがなくてもやってみると楽しいかもしれない。Netlify にデプロイする部分は、後で説明する Cloudflare Pages を使う予定なので無視した。

Cloudflareでドメインを取得

Astro の概要を把握したところで、次にドメインを取得した。Cloudflare Pages では _.pages.dev のようなサブドメインが無料で使えるのだけど、どうせならもっと短くて覚えやすい独自ドメインにしたい。今回はちょうど “weboo.dev” が空いていたので、これを Cloudflare で取得した。

ドメイン取得は、卸売価格での提供をうたっていて最安なのと Cloudflare Pages との連携が簡単になる Cloudflare がおすすめ。参考までに .dev .com .jp ドメインそれぞれの価格を競合他社と比較すると次の表のようになる。こうしてみると同じドメインでも会社によってけっこう価格差があることが分かる。国内だとXserverドメインが頑張っているけど、お名前.comはそれより少しお高め。金額自体は大したことなくても、毎年費用が発生するのでドメインをいくつも持っていると塵も積もれば…である。

CloudflareGoDaddyお名前.comXserverドメイン
.dev1,527円3,025円2,657円
.com1,465円3,325円1,717円1,428円
.jp4,948円3,124円3,102円

※2023年10月30日現在、1ドル=150円で計算。初年度ディスカウントの影響をなくすため、1年分の更新料金で比較している。お名前.comはサービス維持調整費を含む。

ただし、.jpドメインに関しては Cloudflare では対応していないので別のレジストラを利用する必要がある。その場合には、Xserverドメインで取得して、Cloudflare のDNSサーバーを使うみたいなこともできる。余談だけれど、.jpドメインは少し前までWHOIS情報公開代行が不可で氏名と住所が大公開されてしまうため個人では使いにくかった。しかし、今は非公開にできるので大分使いやすくなった。

AstroPaper テーマを導入してカスタマイズ

チュートリアルを一通り終えたところでデザインをどうしようかと調べていたら、 AstroPaper というミニマリストなテーマを見つけてこれにすることにした。日本語で使うに当たって、いくつか修正する必要があったので最低限の設定方法を書いておく。

1. 導入

これはコマンド一発でできる。

npm create astro@latest -- --template satnaing/astro-paper

2. 初期設定

自分のサイトに合わせて src/config.ts を修正する。postPerPage は一覧ページに表示するブログ記事の数、デフォルトは3と少ないので10に増やしておく。

// file: src/config.ts
export const SITE = {
  website: "https://weboo.dev/",
  author: "weboo",
  desc: "ソフトウェア開発や電子工作などモノづくりに関することを徒然と",
  title: "WEBOO.DEV",
  // ogImage: "astropaper-og.jpg",
  lightAndDarkMode: true,
  postPerPage: 10,
};

export const LOCALE = ["ja-JP"];

3. アニメーション効果を無効にする

AstroPaper 3.0 から ViewTransitions によるページ遷移時のアニメーション効果が適用されるようになっている。これが好きな人もいるだろうけど、自分はミニマリストさを維持しておきたかったので、src/layouts/Layout.astro から ViewTransitions を削除して無効化した。また、次項でフォントを変更するので、使用しない無駄なフォントの読み込みもここで一緒に削除しておく。

--- a/src/layouts/Layout.astro
+++ b/src/layouts/Layout.astro
@@ -1,7 +1,6 @@
 ---
 import { SITE } from "@config";
 import "@styles/base.css";
-import { ViewTransitions } from "astro:transitions";

 const googleSiteVerification = import.meta.env.PUBLIC_GOOGLE_SITE_VERIFICATION;

@@ -28,7 +27,7 @@ const socialImageURL = new URL(
 ---

 <!doctype html>
-<html lang="en">
+<html lang="ja">
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width" />
@@ -56,14 +55,6 @@ const socialImageURL = new URL(
     <meta property="twitter:description" content={description} />
     <meta property="twitter:image" content={socialImageURL} />

-    <!-- Google Font -->
-    <link rel="preconnect" href="https://fonts.googleapis.com" />
-    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
-    <link
-      href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,600;0,700;1,400;1,600&display=swap"
-      rel="stylesheet"
-    />
-
     <meta name="theme-color" content="" />

     {
@@ -78,8 +69,6 @@ const socialImageURL = new URL(
       )
     }

-    <ViewTransitions />
-
     <script is:inline src="/toggle-theme.js"></script>
   </head>
   <body>

4. フォントの種類とサイズ変更

こういう外国製テーマにはよくあることなのだけど、英語で見るととても格好いいのに、いざ日本語の文章を入れ込んでみると見づらかったりする。調べてみると、驚いたことにデフォルトフォントが monospace になっていたので一般的な sans-serif に変更した。また漢字を含む日本語は大きい方が読みやすいのでフォントサイズを一回り大きくした。ちょっとした事だけど、この変更だけでサイトの印象が劇的に変わる。

--- a/src/styles/base.css
+++ b/src/styles/base.css
@@ -29,7 +29,7 @@
     display: block;
   }
   body {
-    @apply flex min-h-[100svh] flex-col bg-skin-fill font-mono text-skin-base
+    @apply flex min-h-[100svh] flex-col bg-skin-fill font-sans text-skin-base
     selection:bg-skin-accent selection:bg-opacity-70 selection:text-skin-inverted;
   }
   section,
@@ -92,6 +92,7 @@

   /* ===== scrollbar ===== */
   html {
+    font-size: 17px;
     overflow-y: scroll;
   }
--- a/tailwind.config.cjs
+++ b/tailwind.config.cjs
@@ -56,8 +56,10 @@ module.exports = {
       },
       transparent: "transparent",
     },
-    fontFamily: {
-      mono: ["IBM Plex Mono", "monospace"],
+    extend: {
+      fontFamily: {
+        sans: ["Helvetica Neue", "Arial", "Hiragino Kaku Gothic ProN", "Hiragino Sans", "BIZ UDPGothic", "Meiryo", "sans-serif"],
+      },
     },
     // },
   },

5. OGP画像の日本語対応

AstroPaper には、OGP画像が設定されていない場合に自動で生成してくれる機能があるが、残念ながら日本語に対応していないのでそのままだと真っ白になってしまう。これを日本語表示可能なフォントを利用するように変更する。

  1. BIZ UDPGothic をダウンロード&解凍して public/fonts/ にフォントファイルを置く。当然ながら、ライセンス的に問題のないフォントを使用すること。

  2. src/utils/generateOgImages.tsx を以下のように修正する。

--- a/src/utils/generateOgImages.tsx
+++ b/src/utils/generateOgImages.tsx
@@ -1,26 +1,14 @@
 import satori, { type SatoriOptions } from "satori";
+import fs from "fs/promises";
 import { Resvg } from "@resvg/resvg-js";
 import { type CollectionEntry } from "astro:content";
 import postOgImage from "./og-templates/post";
 import siteOgImage from "./og-templates/site";

-const fetchFonts = async () => {
-  // Regular Font
-  const fontFileRegular = await fetch(
-    "https://www.1001fonts.com/download/font/ibm-plex-mono.regular.ttf"
-  );
-  const fontRegular: ArrayBuffer = await fontFileRegular.arrayBuffer();
-
-  // Bold Font
-  const fontFileBold = await fetch(
-    "https://www.1001fonts.com/download/font/ibm-plex-mono.bold.ttf"
-  );
-  const fontBold: ArrayBuffer = await fontFileBold.arrayBuffer();
-
-  return { fontRegular, fontBold };
-};
-
-const { fontRegular, fontBold } = await fetchFonts();
+const [ fontRegular, fontBold ] = await Promise.all([
+  fs.readFile("./public/fonts/BIZUDPGothic-Regular.ttf"),
+  fs.readFile("./public/fonts/BIZUDPGothic-Bold.ttf"),
+]);

 const options: SatoriOptions = {
   width: 1200,
@@ -28,13 +16,13 @@ const options: SatoriOptions = {
   embedFont: true,
   fonts: [
     {
-      name: "IBM Plex Mono",
+      name: "Biz UDPGothic",
       data: fontRegular,
       weight: 400,
       style: "normal",
     },
     {
-      name: "IBM Plex Mono",
+      name: "BIZ UDPGothic",
       data: fontBold,
       weight: 600,
       style: "normal",

上記の変更で、こんな感じで表示されるようになる。

|w80

自分はさらにカスタマイズして、以下のように表示されるようにしている。この辺のカスタマイズは楽しいけど、凝り出すとキリがないのでほどほどにしておく。

|w80

Cloudflare Pages にデプロイ

そしていよいよ本番環境へのデプロイを行う。Cloudflare Pages は、標準で Astro をサポートしていてとにかく簡単にデプロイできる。無料プランだと並列ビルド不可、月500回のビルド回数制限があるものの、個人ブログ程度ならこれで充分だと思う。あとで release 専用ブランチを作るなどしてビルドブランチを制限しておけば、無駄なビルドが走らないので環境にも優しい。

簡単すぎて説明する必要もなさそうだけど、Cloudflare Pages 連携方法も一応書いておく。

  1. 事前に GitHub にリポジトリを作成してコードを push しておく(パブリックでもプライベートリポジトリでもどちらでも可)

  2. Cloudflare ダッシュボード画面の[Workers & Pages]-[概要]から[Pages]タブを開いて[Git に接続]ボタンを押す。

Cloudflare Pages Deploy

  1. 次に GitHub へのアクセスを許可し、連携するリポジトリを選択して[セットアップの開始]ボタンを押す。

  2. プロジェクト名とプロダクションブランチは、とりあえずデフォルトのままで問題なし。フレームワークは Astro を忘れずに選択。

Cloudflare Pages Deploy

  1. 環境変数(アドバンスド)に以下の値を設定する。
    • TZ = Asia/Tokyo
    • NODE_VERSION = 20 (現時点での最新LTS)

Cloudflare Pages Deploy

  1. [保存してデプロイする]ボタンを押すとビルドとデプロイが始まり、1分も経たずに完了してすぐにサイトが閲覧できるようになる。デプロイされたサイトへのURLリンクがあるので、動作に問題がないか確認して次に進む。

Cloudflare Pages Deploy

  1. 最後に取得したドメインでアクセスできるように、カスタムドメインの設定をする。SSLでのアクセスまで全て自動でやってくれるので、ドメイン名を入力してボタンを押すだけ。

Cloudflare Pages Deploy

以上で実際にブログサイトが動くようになったので、src/content/blog/ フォルダーに Markdown で書いた記事を .md ファイルとして置いて GitHub にプッシュすると本番環境に反映されるようになる。AstroPaper はかなりシンプルなので実際は足りない機能もあるにはあるけれど、ソースコードは見通しがいいので少しずつカスタマイズして機能を追加していこうと思う。