Tech系サービスやガジェットの使い心地、自分の作業環境、資産運用について気が向いたときに記録を残しています。

記事内のAmazonアソシエイト適格販売及び、Google Adsenseでお小遣いを得ています。

Astro1.9からAstro2.0へのアップデートメモ

サークルサイトをAstroで書き直したのだが、リリース日にAstro2.0が発表された上に、泣き所だったMDXコンテンツの呼び出しが改善されていたので即書き直しすることにした。

docs.astro.build

基本はガイド通りに進めていく。

1. コンテンツファイルの場所移動

pageディレクトリに入れていたMDXコンテンツたちを/content/{contenttype}へ移動(今回は/content/portfolioとした)

2. スキーマ定義

config.ts

// 1. Import utilities from `astro:content`
import { z, defineCollection } from "astro:content"
// 2. Define your collection(s)
const portfolioCollection = defineCollection({
  schema: z.object({
    title: z.string(),
    date: z.date(),
    draft: z.boolean(),
    tags: z.array(z.string()),
    cover: z.string().optional(),
    layout: z.string().optional()
  })
})
// 3. Export a single `collections` object to register your collection(s)
//    This key should match your collection directory name in "src/content"
export const collections = {
  portfolio: portfolioCollection
}

3. Astro.glob()していた部分の書き直し 、ルート追加

[slug].astro

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

export async function getStaticPaths() {
  const entries = await getCollection("portfolio")
  return entries.map((entry) => ({
    params: { slug: entry.slug },
    props: { entry }
  }))
}

const { entry } = Astro.props
const { Content } = await entry.render()
---

<Content />

ルーティングはNext.jsっぽい書き方。

markdown用のレイアウトファイルを編集する必要があるかと思ったが、そちらは維持したまま簡単なルーティング用のファイルを置けばとりあえず動いた。 ただ、そのままでは肝心な記事レイアウトのastroコンポーネントで型安全な開発ができないので、レイアウト全体を[slug].astroに寄せている。

github.com

これで、各MarkdownファイルにlayoutのFrontmatterを設定する必要もなくなった。

4. ついでにRSSも追加

pages/rss.xml.ts

import rss from "@astrojs/rss"
import { getCollection } from "astro:content"

export const get = async () => {
  const entries = await getCollection("portfolio")
  return rss({
    title: "Gen's Portfolio(幻想サイクル公式WEBサイト)",
    description:
      "ゲン(@gen_sobunya, gentksb, gensobunya)のポートフォリオサイト兼、同人サークル「幻想サイクル」の公式WEBサイト",
    site: import.meta.env.SITE,
    items: entries.map((entry) => ({
      title: entry.data.title,
      pubDate: entry.data.date,
      link: `/${entry.slug}/`
    }))
  })
}

5. frontmatter処理の変更

data.somefrontmatterで取得するように変更。String前提だった処理も型がついて扱えるようになったので、コードがわかりやすくなった。