Skip to content
143 changes: 86 additions & 57 deletions src/content/docs/en/reference/modules/astro-content.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import {
<Since v="2.0.0" />
</p>

`defineCollection()` is a utility to configure a collection in a `src/content.config.*` file.
A utility to configure a collection in a `src/content.config.*` file.

```ts title="src/content.config.ts"
import { z, defineCollection } from 'astro:content';
Expand Down Expand Up @@ -73,7 +73,7 @@ This function accepts the following properties:
<Since v="5.0.0" />
</p>

A `loader` is either an object or a function that allows you to load data from any source, local or remote, into content collections.
Either an object or a function that allows you to load data from any source, local or remote, into content collections.

[See the `Content Collection` guide](/en/guides/content-collections/#build-time-collection-loaders) for example usage.

Expand All @@ -85,28 +85,28 @@ A `loader` is either an object or a function that allows you to load data from a
<Since v="2.0.0" />
</p>

`schema` is an optional Zod object to configure the type and shape of document frontmatter for a collection. Each value must use [a Zod validator](https://github.com/colinhacks/zod).
An optional Zod object or function that returns a Zod object to configure the type and shape of document frontmatter for a collection. Each value must use [a Zod validator](https://github.com/colinhacks/zod).

[See the `Content Collection` guide](/en/guides/content-collections/#defining-the-collection-schema) for example usage.

### `defineLiveCollection()`

<p>

**Type:** `(input: CollectionConfig) => CollectionConfig`
**Type:** `(config: LiveCollectionConfig) => LiveCollectionConfig`
<Since v="6.0.0" />
</p>

`defineLiveCollection()` is a utility to configure a live collection in a `src/live.config.*` file.
A utility to configure a live collection in a `src/live.config.*` file.

```ts title="src/content.config.ts"
```ts title="src/live.config.ts"
import { defineLiveCollection } from 'astro:content';
import { storeLoader } from '@mystore/astro-loader';
import { storeLoader } from '@example/astro-loader';

const products = defineLiveCollection({
loader: storeLoader({
apiKey: process.env.STORE_API_KEY,
endpoint: 'https://api.mystore.com/v1',
endpoint: 'https://api.example.com/v1',
}),
});

Expand All @@ -121,11 +121,11 @@ This function accepts the following properties:

<p>

**Type:** <code>() => Promise&lt;Array&lt;\{ id: string, [key: string]: any }&gt; | Record&lt;string, Record&lt;string, any&gt;&gt;&gt; | <a href="/en/reference/content-loader-reference/#object-loader-api">Loader</a></code>
<Since v="5.0.0" />
**Type:** `LiveLoader`
<Since v="6.0.0" />
</p>

A `loader` is either an object or a function that allows you to load data from any source, local or remote, into a live content collections.
An object that allows you to load data at runtime from a remote source, into a live content collections.

[See the `Content Collection` guide](/en/guides/content-collections/#creating-a-live-loader) for example usage.

Expand All @@ -137,24 +137,26 @@ A `loader` is either an object or a function that allows you to load data from a
<Since v="6.0.0" />
</p>

`schema` is an optional Zod object to configure the type and shape of document frontmatter for a live collection. Each value must use [a Zod validator](https://github.com/colinhacks/zod).
An optional Zod object to configure the type and shape of your data for a live collection. Each value must use [a Zod validator](https://github.com/colinhacks/zod).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: is the schema property any different for the two collections? I'm wondering whether these should just be combined into one if not?

(Then, the line can say e.g. "When you define a schema in a live collection, it will take precedence over the live loader’s types when you query the collection."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Live collections can't have the function syntax for schemas (i.e. no image helper)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, as Matt said, because they don't share the same type it might be better to have them separated. But we could apply the same changes that you've suggested for loader to reduce the confusion between the two!


{/* TODO: we might want a link here to the reference for building a live loader similar to what we have for build-time collections (ie. https://docs.astro.build/en/reference/content-loader-reference/#object-loader-api) */}
When you define a schema, it will take precedence over the loader’s types when you query the collection.

[See the `Content Collection` guide](/en/guides/content-collections/#using-zod-schemas-with-live-collections) for example usage.

### `reference()`

<p>

**Type:** `(collection: string) => ZodEffects<ZodString, { collection, id: string }>`<br />
**Type:** <code>(collection: <a href="#collectionkey">CollectionKey</a>) => ZodEffects\<ZodString, \{ collection: CollectionKey, id: string \}\></code><br />
<Since v="2.5.0" />
</p>

The `reference()` function is used in the content config to define a relationship, or "reference," from one collection to another. This accepts a collection name and transforms the reference into an object containing the collection name and the reference id.

A function used in the content config to define a relationship, or "reference", from one collection to another. This accepts a collection name and transforms the reference into an object containing the collection name and the reference id.

This example defines references from a blog author to the `authors` collection and an array of related posts to the same `blog` collection:

```ts
```ts title="src/content.config.ts"
import { defineCollection, reference, z } from 'astro:content';
import { glob, file } from 'astro/loaders';

Expand Down Expand Up @@ -188,19 +190,19 @@ const relatedPosts = await getEntries(blogPost.data.relatedPosts);

<p>

**Type:** `(collection: string, filter?: (entry: CollectionEntry<collection>) => boolean) => CollectionEntry<collection>[]`
**Type:** <code>(collection: <a href="#collectionkey">CollectionKey</a>, filter?: (entry: <a href="#collectionentry">CollectionEntry</a>) => boolean) => CollectionEntry[]</code>
<Since v="2.0.0" />
</p>

`getCollection()` is a function that retrieves a list of content collection entries by collection name.
A function that retrieves a list of content collection entries by collection name.

It returns all items in the collection by default, and accepts an optional `filter` function to narrow by entry properties. This allows you to query for only some items in a collection based on `id` or frontmatter values via the `data` object.

```astro
```astro title="src/pages/blog/index.astro"
---
import { getCollection } from 'astro:content';

// Get all `src/content/blog/` entries
// Get all `src/data/blog/` entries
const allBlogPosts = await getCollection('blog');

// Only return posts with `draft: true` in the frontmatter
Expand All @@ -216,25 +218,23 @@ const draftBlogPosts = await getCollection('blog', ({ data }) => {

<p>

**Type:** `(collection: string, filter?: (entry: CollectionEntry<collection>) => boolean) => CollectionEntry<collection>[]`
**Type:** `(collection: string, filter?: LiveLoaderCollectionFilterType) => Promise<LiveDataCollectionResult>`
<Since v="6.0.0" />
</p>

`getLiveCollection()` is a function that retrieves a list of live content collection entries by collection name.
A function that retrieves a list of live content collection entries by collection name.

It returns all items in the collection by default, and accepts an optional `filter` function to narrow by entry properties. This allows you to query for only some items in a collection based on `id` or frontmatter values via the `data` object.
It returns all items in the default collection and accepts an optional `filter` object whose shape is defined by your loader. This allows you to query for only some items in a collection or retrieve data in a different form, depending on your API's capabilities.

```astro
```astro title="src/pages/shop/index.astro"
---
import { getLiveCollection } from 'astro:content';

// Get all `src/content/blog/` entries
const allBlogPosts = await getLiveCollection('blog');
// Get all `products` entries from your API
const allProducts = await getLiveCollection('products');

// Only return posts with `draft: true` in the frontmatter
const draftBlogPosts = await getLiveCollection('blog', ({ data }) => {
return data.draft === true;
});
// Only return `products` that should be featured
const featuredProducts = await getLiveCollection('products', { featured: true });
---
```

Expand All @@ -245,14 +245,14 @@ const draftBlogPosts = await getLiveCollection('blog', ({ data }) => {
<p>

**Types:**
* `(collection: string, id: string) => Promise<CollectionEntry<collection> | undefined>`
* `({ collection: string, id: string }) => Promise<CollectionEntry<collection> | undefined>`
* <code>(collection: <a href="#collectionkey">CollectionKey</a>, id: string) => Promise\<<a href="#collectionentry">CollectionEntry</a> | undefined\></code>
* <code>(\{ collection: <a href="#collectionkey">CollectionKey</a>, id: string \}) => Promise\<<a href="#collectionentry">CollectionEntry</a> | undefined\></code>
<Since v="2.5.0" />
</p>

`getEntry()` is a function that retrieves a single collection entry by collection name and the entry `id`. `getEntry()` can also be used to get referenced entries to access the `data` or `body` properties:
A function that retrieves a single collection entry by collection name and the entry `id`. `getEntry()` can also be used to get referenced entries to access the `data` or `body` properties:

```astro
```astro title="src/pages/index.astro"
---
import { getEntry } from 'astro:content';

Expand All @@ -273,24 +273,21 @@ See the `Content Collections` guide for examples of [querying collection entries

<p>

**Types:**
* `(collection: string, id: string) => Promise<LiveDataEntryResult>`
* `({ collection: string, filter: LiveLoaderEntryFilterType }) => Promise<LiveDataEntryResult>`
**Type:** `(collection: string, filter: string | LiveLoaderEntryFilterType) => Promise<LiveDataEntryResult>`
<Since v="6.0.0" />
</p>

`getLiveEntry()` is a function that retrieves a single live collection entry by collection name and the entry `id`. `getLiveEntry()` can also be used to get referenced entries to access the `data` or `body` properties:
A function that retrieves a single live collection entry by collection name and an optional filter either as an `id` string or as a type-safe object.

```astro
```astro title="src/pages/blog/[id].astro"
---
import { getLiveEntry } from 'astro:content';

const enterprisePost = await getLiveEntry('blog', 'enterprise');

const picardProfile = await getLiveEntry('captains', 'picard');

// Get the profile referenced by `data.captain`
const enterpriseCaptainProfile = await getLiveEntry(enterprisePost.data.captain);
const liveCollectionsPost = await getLiveEntry('blog', Astro.params.id);
const mattDraft = await getLiveEntry('blog', {
status: 'draft',
author: 'matt',
});
---
```

Expand All @@ -300,13 +297,13 @@ See the `Content Collections` guide for examples of [querying collection entries

<p>

**Type:** `(Array<{ collection: string, id: string }>) => Array<CollectionEntry<collection>>`
**Type:** <code>(\{ collection: <a href="#collectionkey">CollectionKey</a>, id: string \}[]) => <a href="#collectionentry">CollectionEntry</a>[]</code>
<Since v="2.5.0" />
</p>

`getEntries()` is a function that retrieves multiple collection entries from the same collection. This is useful for [returning an array of referenced entries](/en/guides/content-collections/#defining-collection-references) to access their associated `data` and `body` properties.
A function that retrieves multiple collection entries from the same collection. This is useful for [returning an array of referenced entries](/en/guides/content-collections/#defining-collection-references) to access their associated `data` and `body` properties.

```astro
```astro title="src/pages/blog/enterprise/index.astro"
---
import { getEntries, getEntry } from 'astro:content';

Expand All @@ -321,7 +318,7 @@ const enterpriseRelatedPosts = await getEntries(enterprisePost.data.relatedPosts

<p>

**Type:** `(entry: CollectionEntry) => Promise<RenderedEntry>`
**Type:** <code>(entry: <a href="#collectionentry">CollectionEntry</a>) => Promise\<RenderResult\></code>
<Since v="5.0.0" />
</p>

Expand Down Expand Up @@ -352,8 +349,6 @@ const { Content, headings, remarkPluginFrontmatter } = await render(entry);
import type {
CollectionEntry,
CollectionKey,
ContentCollectionKey,
DataCollectionKey,
SchemaContext,
} from 'astro:content';
```
Expand All @@ -366,45 +361,79 @@ Query functions including [`getCollection()`](#getcollection), [`getEntry()`](#g
import type { CollectionEntry } from 'astro:content';
```

`CollectionEntry` is a generic type. Use it with the name of the collection you're querying.
A generic type to use with the name of the collection you're querying to represent a single entry in that collection.
For example, an entry in your `blog` collection would have the type `CollectionEntry<'blog'>`.

Each `CollectionEntry` is an object with the following values:

#### `id`

<p>

**Type:** `string`
</p>

A unique ID. Note that all IDs from Astro's built-in `glob()` loader are slugified.

#### `collection`

**Example Type:** `'blog' | 'authors' | ...`
<p>

**Type:** [`CollectionKey`](#collectionkey)
</p>

The name of a collection in which entries are located. This is the name used to reference the collection in your schema, and in querying functions.

#### `data`

<p>

**Type:** `CollectionSchema<TCollectionName>`
</p>

An object of frontmatter properties inferred from your collection schema ([see `defineCollection()` reference](#definecollection)). Defaults to `any` if no schema is configured.

#### `body`

<p>

**Type:** `string`
</p>

A string containing the raw, uncompiled body of the Markdown or MDX document.

#### `rendered`

<p>

**Type:** `RenderedContent | undefined`
</p>

The rendered content of a Markdown or HTML entry from a CMS as stored by your loader.

#### `filePath`

<p>

**Type:** `string | undefined`
</p>

The path to an entry relative to your project directory. This value is only available for local entries.

### `CollectionKey`

<p><Since v="3.1.0" /></p>
<p>

**Example Type:** `'blog' | 'authors' | ...`<br />
<Since v="3.1.0" />
</p>

A string union of all collection names defined in your `src/content.config.*` file. This type can be useful when defining a generic function wrapping the built-in `getCollection()`.

```ts
```ts title="src/utils/collections.ts"
import { type CollectionKey, getCollection } from 'astro:content';

async function queryCollection(collection: CollectionKey) {
export async function queryCollection(collection: CollectionKey) {
return getCollection(collection, ({ data }) => {
return data.draft !== true;
});
Expand All @@ -419,7 +448,7 @@ This includes the following property:

- `image` - The `image()` schema helper that allows you [to use local images in Content Collections](/en/guides/images/#images-in-content-collections)

```ts
```ts title="src/content.config.ts"
import { defineCollection, z, type SchemaContext } from "astro:content";

export const imageSchema = ({ image }: SchemaContext) =>
Expand Down