サークルサイトをAstroで書き直したのだが、リリース日にAstro2.0が発表された上に、泣き所だったMDXコンテンツの呼び出しが改善されていたので即書き直しすることにした。
基本はガイド通りに進めていく。
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に寄せている。
これで、各Markdownファイルにlayout
のFrontmatterを設定する必要もなくなった。
4. ついでにRSSも追加
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前提だった処理も型がついて扱えるようになったので、コードがわかりやすくなった。