コンテンツコレクション
追加:
astro@2.0.0
コンテンツコレクションは、Astroプロジェクトでコンテンツを管理し、オーサリングするもっとも良い方法です。コレクションはドキュメントを整理し、フロントマターを検証、すべてのコンテンツに対して自動的にTypeScriptの型安全性を提供します。
コンテンツコレクションとは?
セクションタイトル: コンテンツコレクションとは?予約されているプロジェクトディレクトリsrc/content
の中にあるトップレベルのディレクトリは、1つのコンテンツコレクションを表わします。たとえばsrc/content/newsletter
やsrc/content/authors
などになります。src/content
ディレクトリの中に入れられるのは、コンテンツコレクションだけです。このディレクトリは他のものには使えません。
コレクションエントリーは、コンテンツコレクションディレクトリ内に保存されたコンテンツのことです。エントリーには、Markdown(.md
)やMDX (.mdx
MDXインテグレーション (EN)を使用)などのコンテンツオーサリングフォーマットや、YAML(.yaml
)やJSON(.json
)などのデータフォーマットを使用できます。コンテンツの検索と整理を容易にするため、ファイルには一貫性のある命名スキーム(小文字、スペースの代わりにダッシュ)の使用をおすすめしますが、これは必須ではありません。また、ファイル名の前にアンダースコア(_)を付けることで、ビルド対象からエントリーを除外できます。
ディレクトリsrc/content/
ディレクトリnewsletter/ “newsletter”コレクション
- week-1.md コレクションエントリー
- week-2.md コレクションエントリー
- week-3.md コレクションエントリー
コレクションができたら、Astroの組み込みコンテンツAPIを使ってコンテンツのクエリを始められます。
“.astro”ディレクトリ
セクションタイトル: “.astro”ディレクトリAstroは、コンテンツコレクションの重要なメタデータを、プロジェクト内の.astro
ディレクトリに保存します。このディレクトリを維持または更新するために、何かする必要はありません。プロジェクトでの作業中は、このディレクトリを完全に無視してください。
.astro
ディレクトリは、astro dev
コマンドやastro build
コマンドを実行すると常に自動で更新されます。必要に応じてastro sync
を実行し、手動で.astro
ディレクトリを更新できます。
バージョン管理にGitを使っている場合は、.gitignore
に .astro
を追加して.astro
ディレクトリを無視することをおすすめします。以下は、このディレクトリとその中のファイルを無視するようにGitに伝えます。
複数のコレクションによる整理
セクションタイトル: 複数のコレクションによる整理2つのファイルが異なる種類のコンテンツ(例えばブログの投稿と著者のプロフィール)を表す場合、それらは異なるコレクションに属する可能性が高いでしょう。多くの機能(フロントマターの検証、TypeScriptの自動型安全性)では、コレクション内のすべてのエントリーが同様の構造を共有する必要がありますので、これは重要です。
さまざまなタイプのコンテンツを扱うことになったら、それぞれのタイプを表す複数のコレクションを作成する必要があります。プロジェクトには、いくつでも異なるコレクションを作成できます。
ディレクトリsrc/content/
ディレクトリnewsletter/
- week-1.md
- week-2.md
ディレクトリblog/
- post-1.md
- post-2.md
ディレクトリauthors/
- grace-hopper.json
- alan-turing.json
サブディレクトリを使った整理
セクションタイトル: サブディレクトリを使った整理コンテンツコレクションは、常にsrc/content/
ディレクトリ内のトップレベルのフォルダです。コレクションを別のコレクションの中に入れ子にはできません。しかし、サブディレクトリを使ってコレクション内のコンテンツを整理できます。
たとえば、1つのdocs
コレクション内で多言語の翻訳を整理するために、次のディレクトリ構造を使えます。このコレクションをクエリするとき、ファイルパスを使用して言語によって結果をフィルタできます。
ディレクトリsrc/content/
ディレクトリdocs/ このコレクションは、言語別に整理したサブディレクトリを使用
ディレクトリen/
- …
ディレクトリes/
- …
ディレクトリde/
- …
コレクションの定義
セクションタイトル: コレクションの定義src/content/config.ts
ファイルは省略できます。しかし、コレクションを定義しないと、フロントマターのスキーマ検証やTypeScriptの自動型付けなど、コレクションのいくつかの優れた機能が使えなくなります。
コンテンツコレクションを最大限に活用するには、プロジェクト内にsrc/content/config.ts
ファイルを作成してください(.js
と.mjs
の拡張子もサポートされています)。これは、Astroがコンテンツコレクションを設定するために自動的に読み込んで使用する特別なファイルです。
TypeScriptのセットアップ
セクションタイトル: TypeScriptのセットアップtsconfig.json
ファイルでAstroのTypeScript設定をstrict
またはstrictest
に設定していない場合は、tsconfig.json
を更新してstrictNullChecks
を有効にする必要があるかもしれません。
Astroプロジェクトで.js
または.mjs
ファイルを使用する場合、tsconfig.json
でallowJs
を有効にすることで、インテリセンスとエディタでの型チェックを有効にできます。
コレクションスキーマの定義
セクションタイトル: コレクションスキーマの定義スキーマは、コレクション内の一貫したフロントマターまたはエントリーデータを強制します。スキーマは、このデータへの参照やクエリが必要なときに、それが予測可能な形で存在することを保証します。ファイルがコレクションスキーマに違反している場合、Astroは役にたつエラーを表示してお知らせします。
スキーマはAstroのコンテンツに対する自動的なTypeScriptの型付けにも力を発揮します。コレクションにスキーマを定義すると、Astroは自動的にTypeScriptインターフェイスを生成して適用します。その結果、コレクションをクエリする際には、プロパティの自動補完や型チェックを含むTypeScriptが完全にサポートされます。
最初のコレクションを定義するには、src/content/config.ts
ファイルがまだ存在しなければ、このファイルを作成します(.js
と .mjs
の拡張子もサポートされています)。
astro:content
から適切なユーティリティをインポートします。- 検証したい各コレクションを定義します。これには、コレクションがMarkdownのようなコンテンツオーサリングフォーマット(
type: 'content'
)であるか、JSONやYAMLのようなデータフォーマット(type: 'data'
)であるかを指定するtype
(Astro v2.5.0で導入)が含まれます。また、フロントマターやエントリーデータの形を定義するschema
も含まれます。 - コレクションを登録するために、単一の
collections
オブジェクトをエクスポートします。
複数のコレクションの定義
セクションタイトル: 複数のコレクションの定義defineCollection()
は、複数のスキーマを作成するために何度でも使えます。 すべてのコレクションは、単一のcollections
オブジェクトの内部からエクスポートする必要があります。
プロジェクトが成長するにつれて、コードベースを再編成し、src/content/config.ts
ファイルからロジックを移動することも自由にできます。スキーマを別々に定義することは、複数のコレクションでスキーマを再利用したり、プロジェクトの他の部分とスキーマを共有したりするのに便利です。
サードパーティのコレクションスキーマの使用
セクションタイトル: サードパーティのコレクションスキーマの使用外部のnpmパッケージなど、どこからでもコレクションスキーマをインポートできます。これは、独自のコレクションスキーマを提供するテーマやライブラリを使用するときに便利です。
Zodによるデータ型の定義
セクションタイトル: Zodによるデータ型の定義AstroはZodを使ってコンテンツスキーマを動かしています。Zodを利用すると、Astroはコレクション内のすべてのファイルのフロントマターを検証し、プロジェクト内からコンテンツをクエリする際に自動的にTypeScriptの型を提供できます。
AstroでZodを使うには、"astro:content"
からz
ユーティリティをインポートします。これはZodライブラリの再エクスポートで、Zodのすべての機能をサポートしています。Zodがどのように動作し、どのような機能が利用可能かについての完全なドキュメントは、ZodのREADMEを参照してください。
コレクション参照の定義
セクションタイトル: コレクション参照の定義コレクションエントリーは、他の関連するエントリーを「参照」することもできます。
Collections APIのreference()
関数を使うと、コレクションスキーマのプロパティを別のコレクションのエントリーとして定義できます。たとえば、すべてのspace-shuttle
エントリーに、型チェック、オートコンプリート、バリデーションにpilot
コレクションのスキーマを使用するpilot
プロパティを含めるように要求できます。
よくある例は、JSONとして保存された再利用可能な著者プロフィールや、同じコレクションに保存された関連投稿URLを参照するブログ投稿です。
このブログ記事の例では、関連記事のslug
と投稿者のid
を指定しています。
カスタムスラグの定義
セクションタイトル: カスタムスラグの定義type: 'content'
を使用している場合、すべてのコンテンツエントリーはファイルid
(EN)からURLフレンドリーなslug
プロパティを生成します。このスラグは、コレクションからエントリーを直接クエリするために使用されます。また、コンテンツから新しいページやURLを作成するときにも便利です。
ファイルのフロントマターに独自のslug
プロパティを追加すると、エントリーの生成されたスラグをオーバーライドできます。これは他のWebフレームワークの”permalink”機能に似ています。"slug"
は特別な予約されたプロパティ名で、カスタムコレクションschema
では許可されず、エントリーのdata
プロパティには表示されません。
コレクションのクエリ
セクションタイトル: コレクションのクエリAstroには、コレクションにクエリを発行して1つ(または複数)のコンテンツエントリーを返す関数が2つあります。getCollection()
(EN)とgetEntry()
(EN)です。
どちらの関数も、CollectionEntry
(EN)型で定義されたコンテンツエントリーを返します。
参照データへのアクセス
セクションタイトル: 参照データへのアクセススキーマで定義されている参照は、最初にコレクションエントリーをクエリした後で、個別にクエリする必要があります。getEntry()
関数を再度使用するか、またはgetEntries()
を使用して、返されたdata
オブジェクトから参照されるエントリーを取得できます。
コレクションクエリのフィルタリング
セクションタイトル: コレクションクエリのフィルタリングgetCollection()
はオプションの”filter”コールバックを受け取り、エントリーのid
やdata
(フロントマター)プロパティに基づいてクエリをフィルタリングします。type: 'content'
のコレクションについては、slug
に基づいてフィルタリングもできます。
slug
プロパティはコンテンツコレクションに固有のもので、JSONやYAMLのコレクションをフィルタリングするときには利用できません。
これを使用して、コンテンツを好きな基準でフィルタリングできます。たとえば、draft
のようなプロパティでフィルタリングして、下書きのブログ記事がブログに公開されないようにできます。
開発サーバーの実行時にのみ閲覧可能で、本番用にはビルドされない下書き(draft)ページも作成できます。
filterの引数は、コレクション内の入れ子ディレクトリによるフィルタリングもサポートします。id
にはネストされた完全なパスが含まれるので、各id
の先頭でフィルタリングして、特定のネストされたディレクトリからのアイテムだけを返せます。
Astroテンプレートでのコンテンツの使用
セクションタイトル: Astroテンプレートでのコンテンツの使用コレクションエントリーをクエリすると、Astroコンポーネントテンプレートの内部で各エントリーに直接アクセスできます。これにより、コンテンツへのリンク(コンテンツslug
を使用)やコンテンツに関する情報(data
プロパティを使用)などのHTMLをレンダリングできます。
コンテンツをHTMLにレンダリングする方法については、下記のコンテンツをHTMLにレンダリングするを参照してください。
コンテンツをプロパティとして渡す
セクションタイトル: コンテンツをプロパティとして渡すコンポーネントは、コンテンツエントリー全体をプロパティとして渡すこともできます。
この場合、CollectionEntry
(EN)ユーティリティを使用して、TypeScriptでコンポーネントのプロパティを適切に型付けできます。 このユーティリティは、コレクションスキーマの名前と一致する文字列引数を取り、そのコレクションのスキーマのすべてのプロパティを継承します。
コンテンツをHTMLにレンダリングする
セクションタイトル: コンテンツをHTMLにレンダリングするクエリされたエントリーのrender()
関数プロパティを使用して、MarkdownおよびMDXエントリーをHTMLにレンダリングできます。この関数を呼び出すと、<Content />
コンポーネントとレンダリングされたすべての見出しのリストを含む、レンダリングされたコンテンツとメタデータにアクセスできます。
コンテンツからルーティングを生成
セクションタイトル: コンテンツからルーティングを生成コンテンツコレクションはsrc/pages/
ディレクトリの外に保存されます。つまり、デフォルトではコレクション項目に対してルーティングは生成されません。コレクション項目からHTMLページを生成するには、手動で新しい動的ルーティングを作成する必要があります。動的ルーティングは、リクエストのパラメーター (例:src/pages/blog/[...slug].astro
のAstro.params.slug
) をマッピングして、コレクション内の正しいエントリーを取得します。
ルーティングを生成する正確な方法は、ビルドの出力モードによって異なります。モードはstatic(デフォルト)またはserver(SSRの場合)です。
静的出力のビルド(デフォルト)
セクションタイトル: 静的出力のビルド(デフォルト)静的なウェブサイトを構築する場合(Astroのデフォルトの動作)、ビルド中に1つのsrc/pages/
コンポーネントから複数のページを作成するには、getStaticPaths()
(EN)関数を使用します。
getStaticPaths()
内でgetCollection()
を呼び出し、コンテンツまたはデータををクエリします。それから、各コンテンツエントリーのslug
プロパティ(コンテンツコレクション)またはid
プロパティ(データコレクション)を使用して、新しいURLパスを作成します。
これにより、blog
コレクションの各エントリーに新しいページが生成されます。たとえば、src/content/blog/hello-world.md
のエントリーはhello-world
というスラグを持つので、最終的なURLは/posts/hello-world/
となります。
カスタムスラグに/
文字が含まれ、複数のパスセグメントを持つURLを生成する場合は、この動的ルーティングページの.astro
ファイル名にレストパラメータ([...slug]
)を使用する必要があります。
サーバー出力のビルド(SSR)
セクションタイトル: サーバー出力のビルド(SSR)動的なウェブサイトを構築する場合(AstroのSSRサポートを使用する場合)、ビルド時にパスを生成する必要はありません。そのかわり、ページでは(Astro.request
あるいはAstro.params
を使って)リクエストを調べてslug
を見つけ、getEntry()
(EN)を使って取得しなければなりません。
GitHubのブログチュートリアルデモコード または StackBlitzで開く の src/pages/
フォルダを探せば、ブログ記事のリストやタグページなど、コレクションからページを作成する完全な例を見れます!
ファイルベースのルーティングからの移行
セクションタイトル: ファイルベースのルーティングからの移行src/pages/
内のサブフォルダーでMarkdownまたはMDXファイルを使用するブログなどの既存のAstroプロジェクトがある場合は、関連するコンテンツまたはデータファイルをコンテンツコレクションに移行することを検討してください。
ブログ作成チュートリアルの完成プロジェクトのコードベースを使用するステップバイステップのチュートリアル (EN)で、基本的なブログの例をsrc/pages/posts/
からsrc/content/posts
に変換する方法を確認してください。
JSONスキーマの生成を有効にする
セクションタイトル: JSONスキーマの生成を有効にする
追加:
astro@4.13.0
data
型のコレクションを使用している場合、Astroはインテリセンスと型チェックを行うために、エディタ用のJSONスキーマファイルを自動生成します。src/content/config.ts
で定義されたコレクションに基づいて、プロジェクト内の各データコレクションごとに、zod-to-json-schema
と呼ばれるライブラリを使用して個別のファイルが作成されます。
この機能では、コレクションの各データ入力ファイルで、スキーマのファイルパスを $schema
の値として手動で設定する必要があります。
または、エディタの設定でこの値を設定することもできます。例えば、VSCodeのjson.schemas
設定でこの値を設定するには、マッチするファイルのパスとJSONスキーマの場所を指定します。
ビルドキャッシュを有効にする
セクションタイトル: ビルドキャッシュを有効にする
追加:
astro@3.5.0
Experimental
大規模なコレクションを扱っている場合は、experimental.contentCollectionCache
フラグを使用してキャッシュされたビルドを有効にするとよいでしょう。この実験的な機能は、Astroのビルドプロセスを最適化し、変更されていないコレクションを保存してビルド間で再利用できるようにします。
多くの場合、これによりビルドパフォーマンスが大幅に向上します。
この機能が安定するまで、保存されたキャッシュで問題が発生する可能性があります。次のコマンドを実行すると、いつでもビルドキャッシュをリセットできます。
Remarkでフロントマターを修正
セクションタイトル: Remarkでフロントマターを修正非推奨。Remarkとrehypeプラグインは生のMarkdownまたはMDXドキュメントのフロントマターにアクセスします。これはremarkPluginFrontmatter
のフロントマターがあなたの型セーフschema
とは別に扱われ、Astroを通して適用された変更やデフォルトは反映されません。使用は自己責任です!
Astroは、フロントマターを直接変更するremarkまたはrehypeプラグインをサポートしています。render()
から返されるremarkPluginFrontmatter
プロパティを使うと、コンテンツエントリー内でこの変更されたフロントマターにアクセスできます。
remarkやrehypeのパイプラインは、コンテンツがレンダリングされたときにのみ実行されます。そのため、render()
をコールした後にremarkPluginFrontmatter
を使用できるようになります。対照的に、getCollection()
やgetEntry()
はコンテンツをレンダリングしないので、これらの値を直接返すことはできません。
フロントマターでの日付の扱い
セクションタイトル: フロントマターでの日付の扱いコンテンツコレクションではいくつかの日付フォーマットが可能ですが、コレクションのスキーマはMarkdownまたはMDX YAMLのフロントマターで使用されているフォーマットと一致しなければなりません。
YAMLは日付を表現するためにISO-8601の標準を使います。yyyy-mm-dd
(例 2021-07-28
)というフォーマットとz.date()
というスキーマタイプを使います:
タイムゾーンが指定されていない場合、日付の書式はUTCで指定されます。タイムゾーンを指定する必要がある場合は、ISO 8601 形式を使うことができます。
完全なUTCタイムスタンプからYYYY-MM-DD
だけをレンダリングするには、JavaScriptのslice
メソッドを使用してタイムスタンプを削除します:
toLocaleDateString
を使って日、月、年をフォーマットする例を見るには、Astro公式ブログテンプレートの<FormattedDate />
コンポーネントを参照してください。