Astroでブログを作った話
この記事はmaccha Advent Calender 2024の6日目の記事です。
昨日はmacchaさんによる「Google Apps ScriptのソースコードをGitHubで管理し,claspによるデプロイ作業をGitHub Actionsで自動化する 」でした。
あんまりGASを使ってはいない身ではあるものの、便利なことだけはわかるのでいつか使わせていただきます。
本題
実は、このブログを作ったのは今年の11月のことだ。その時の記録を残しておこう。
きっかけ
去年ぐらいからブログ予定地としてGitHub Pagesを使ったページを公開していたが、単にUNDER CONSTRUCTIONと書かれているだけのページであった。ここから一切手を付けずに放置して今年の11月になってしまった。
8月ごろにとある理由で新たなドメイン名hydrogen1.devを取得した私は、ついでにこのブログも新しく作り直そうと思い立った。そこで友人のryota2357君が使っているAstroという静的サイトジェネレーターを使ってみることにした。
このサイトのデザインの大部分はryota2357君のサイトを参考に作ったといっても過言ではない。感謝。
準備
まず、GitHubのリポジトリからUNDER CONSTRUCTIONのページを消し飛ばし次のコマンドを実行した。
npm create astro@latestテンプレートは公式が提供しているブログ用のものを選択した。その後、npm run devを実行してローカルでサイトを確認した。
開発の準備として、tsconfig.jsonを編集して@/aaaをsrc/aaaと解釈するようにした。
    "paths": {
      "@/*": ["./src/*"]
    }また、僕は今日のhydrogen Advent Calenderの記事にもある通り数式を使うことが多いので、を使えるようにするためにremark-mathとrehype-katexをインストールした。
npm install remark-math rehype-katexastro.config.mjsに以下のように設定を追加した。
import { remarkMath } from 'remark-math'
import rehypeKatex from 'rehype-katex'
...
export default {
  ...
  remarkPlugins: [remarkMath],
  rehypePlugins: [rehypeKatex],
  ...
}以前から使ってみたいと思っていたtailwindも導入した。
npx astro add tailwindastro.config.mjsに以下のように設定を追加した。
import { tailwind } from '@astro/tailwind'
...
export default {
  ...
  plugins: [
    ...,
    tailwind()
  ],
  ...
}tailwindのデフォルトの設定では、番号付きリストタグ<ol>の要素に番号がつかないので、tailwind.config.jsに以下の設定を追加した。
import plugin from 'tailwindcss/plugin'
export default {
  ...
  plugins: [
    plugin(function({ addBase, theme }) {
      addBase({
        'ol': {
          listStyleType: theme('listStyleType.decimal'),
          listStylePosition: 'inside',
        },
      })
    }),
  ]
  ...
}これで、記事本体のMarkdownに番号付きリストを使うことができるようになった。
記事をMarkdownで書く
記事の一覧を管理するためAstroのcollectionを使って次のように属性を定義した。
const blog = defineCollection({
    type: 'content',
    schema: z.object({
        title: z.string(),
        description: z.string(),
        pubDate: z.coerce().date(),
        tags: z.array(z.string()),
        draft: z.boolean().optional(),
    }),
})そして、ブログ記事を表示できるようにすべく[year]/[slug].astroを作成し、getStaticPathsを定義した。
このメゾットはparamsに[year]などのカッコ内の文字列としてあり得るものを、その時にpropsに渡す値の配列を返す。
このようにして、柔軟にページを生成することができる。
そして、記事の属性自体はMarkdownファイルの先頭に次のように記述することで、Astroが自動的に認識する。
---
title: "Astroでブログを作った話"
description: "maccha Advent Calender 2024 day 6"
pubDate: "2024-12-06T11:15"
tags: ["maccha Advent Calender 2024", "Astro"]
---タグで整理
記事をタグで整理するために、記事のtags属性で指定したタグをもとに記事を分類するページを作成した。
const allTags = Array.from(allBlogPosts.flatMap(post => post.data.tags)
        .reduce((map, tag) => map.set(tag, (map.get(tag) ?? 0) + 1), new Map<string, number>())
        .entries())
    .map(([tag, count]) => ({ tag, count }));このようにして、各タグの名前と記事数を取得し、それをもとにタグ一覧ページを作成した。
まとめ
こんな感じでこのブログを作った。まだまだ改善点は多いが、とりあえずはこれでいいだろう。
明日はUdon君によるアドカレ乱立2024についての記事です。