Home

Bluesky

Astro 4.14 Content Layer API

ubanis(Bluesky) 2024年8月20日

オリジナルURL https://ubanis.com/note/astro414_content/

Astro 4.14 Content Layer API

Astro4.14になってContents Collectionに替わる予定のContent Layer APIが実装(実験的)されたので自分のサイトに設定してみた。

参考

https://astro.build/blog/astro-4140/

https://docs.astro.build/en/reference/configuration-reference/#migrating-an-existing-content-collection-to-use-the-content-layer-api

ブログ用markdownファイルの移動

今までの/src/content/から/src/data/へブログ用markdownファイルを移動する。

Content Layerでは/src/content/の中にあるmarkdownファイルを処理しないのでエラーになる。

/src/content/config.tsは動かしてはいけない。

astro.config.mjs に追記

まだ実験的なので以下のように追記する

export default defineConfig({
  experimental: {
    contentLayer: true,
    //省略
  },

/src/content/config.ts の修正

astro/loadersからglobをインポートする

import { glob } from "astro/loaders";

Collection に loader を追加

const blogCollection = defineCollection({
  loader: glob({ pattern: "**/*.(md|mdx)", base: "./src/data/blog" }),
  schema: z.object({
    title: z.string(),
    date: z.coerce.date(),
    //省略
export const collections = {
  blog: blogCollection,
};

slug を id にする

Content Layerではslugは存在しないので各所のslugをidにする

ファイル名も変える
[...slug].astro -> [...id].astro
// slug: entry.slug のようなところも id に
export async function getStaticPaths() {
  const blogEntries = await getCollection(BLOG_NAME);
  const numberOfPosts = blogEntries.length;
  return blogEntries.sort(sortByDate).map((entry, i) => ({
    params: { id: entry.id },
    props: {
      entry,
      prevPost: i + 1 === numberOfPosts ? "" : blogEntries[i + 1],
      nextPost: i === 0 ? "" : blogEntries[i - 1],
    },
  }));
}

// urlを作るときに参照するのも id
const url = post.data.baseUrl ? post.data.baseUrl + post.id : "/" + post.id + "/";

その他各所slugをidに変更した。

renderの変更

const { Content, headings } = await entry.render();
// ↑これを以下のようにする


// インポートしたrenderを使う
import { getCollection, render } from "astro:content";

const { Content, headings } = await render(entry);

サイトの画像

Astro 4.14とは関係ないがサイトの画像変換のAstro Remark Eleventy Image がVercelでよく画像生成を失敗したりするので画像変換をAstroに任せることにした。

それに伴い各画像ファイルはpublicから/src/assets/images/へ移動した。

markdown内の画像にclassをつけることも EleventyがやっていたのでBridgy Fedに必要なu-photoクラスがつけられなくなってしまった。

rehype-add-classなどでclassを付与することもやってみたがpages内のmarkdownファイルだとclassが正しく付与されるがContent Layerのmarkdownファイルには<img className="u-photo">とつけられてしまう。

現在対処方法がないので画像にu-photoをつける場合はmdxファイルにするしかない。