Skip to content

Commit

Permalink
update to new slug changes
Browse files Browse the repository at this point in the history
  • Loading branch information
FredKSchott committed Jan 23, 2023
1 parent fbccd92 commit 5bf17de
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 63 deletions.
63 changes: 9 additions & 54 deletions src/pages/en/guides/content-collections.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -236,20 +236,16 @@ defineCollection({

Every content entry generates a URL-friendly `slug` property from its file `id`. The slug is used to query the entry directly from your collection. It is also useful when creating new pages and URLs from your content.

To customize the generated `slug` value, you can manually override Astro's default behavior by providing a `slug()` function in `defineCollection()`. Whatever value you return from this function will be used as the new `slug` property for each entry.
You can override an entry's generated slug by adding your own `slug` property to the file frontmatter. This is similar to the "permalink" feature of other web frameworks. `"slug"` is a special, reserved property name that is not allowed in your custom collection `schema` and will not appear in your entry's `data` property.

```ts {4-6}
// Example: Override the default entry slug with a custom value.
const blogCollection = defineCollection({
slug: ({ id, defaultSlug }) => {
return myCustomSlugProcessor(id) || defaultSlug;
},
});
```md {3}
---
title: My Blog Post
slug: my-custom-slug/supports/slashes
---
Your blog post content here.
```

For performance reasons, the `slug()` function does not have access to your content's body or frontmatter data. If you need these values to generate your slug, you should do that directly inside the `src/pages` Astro component responsible for rendering your content. See [Generating custom routes](#generating-custom-routes) for more details.


## Querying Collections

Astro provides two functions to query a collection and return one (or more) content entries: [`getCollection()`](/en/reference/api-reference/#getcollection) and [`getEntryBySlug()`](/en/reference/api-reference/#getentrybyslug).
Expand Down Expand Up @@ -349,9 +345,9 @@ const { Content, headings } = await entry.render();

## Generating Routes from Content

Because content collections live outside of the `src/pages/` directory, it's up to you to create [dynamic routes](/en/core-concepts/routing/#dynamic-routes) that will render your content and any collection entries to HTML.
Content collections are stored outside of the `src/pages/` directory. You will need to create a new [dynamic route](/en/core-concepts/routing/#dynamic-routes) to generate HTML pages from your collection entries. Your dynamic route will map the incoming request param (ex: `Astro.params.slug` in `src/pages/blog/[slug].astro`) to fetch the correct entry inside a collection.

The way that you generate routes in Astro depends on your build [`output`](/en/reference/configuration-reference/#output) mode: 'static' (the default) or 'server' (for SSR).
The way that you do this is different, depending on your build [`output`](/en/reference/configuration-reference/#output) mode: 'static' (the default) or 'server' (for SSR).

### Building for static output (default)

Expand Down Expand Up @@ -400,47 +396,6 @@ const { Content } = await entry.render();
<Content />
```

### Generating custom routes

The `slug()` function in `defineCollection()` lets you customize how a content entry `slug` value is created. However, this function does not have access to any frontmatter.

You can still create custom URLs from your content frontmatter inside the `getStaticPaths()` function, when building for static output. For example, to create a custom URL for each blog post based on its `permalink` frontmatter property, you could do the following:

```astro "entry.data.permalink"
---
// src/pages/posts/[slug].astro
// 1. Query the collection and generate a new path for each entry,
// based on its "permalink" frontmatter property.
export async function getStaticPaths() {
const blogEntries = await getCollection('blog');
return blogEntries.map(entry => ({
params: { slug: entry.data.permalink || entry.data.slug },
props: { entry },
}));
}
// 2. When its time to render, you can get the entry directly from the prop.
const { entry } = Astro.props;
---
```

If you are building for server output (SSR), you would do a similar lookup of the entire collection on every request to find your matching entry. However this is not recommended for large collections, where loading the entire collection on every request may slow down your page response time.

```astro "entry.data.permalink"
---
// src/pages/posts/[slug].astro
import { getEntryBySlug } from 'astro:content';
// 1. Get the slug from the incoming server request
const { slug } = Astro.params;
// 2. Query and filter the entire collection
const blogEntries = await getCollection('blog', (entry) => {
return (entry.data.permalink || entry.slug) === slug;
});
// 3. (Optional) render the entry to HTML in the template
const { Content } = await entry.render();
---
<h1>{entry.data.title}</h1>
<Content />
```

## Modifying Frontmatter with Remark

Expand Down
11 changes: 2 additions & 9 deletions src/pages/en/reference/api-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -722,9 +722,6 @@ const blog = defineCollection({
title: z.string(),
permalink: z.string().optional(),
}),
slug({ id, data, defaultSlug, body }) {
return data.permalink ?? defaultSlug;
}
});

// Expose your defined collection to Astro
Expand All @@ -738,13 +735,9 @@ This function accepts the following properties:

**Type:** `TSchema extends ZodType`

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

#### `slug()`

**Type:** `(entry: { defaultSlug: string } & Omit<CollectionEntry, 'slug'>) => string | undefined`
`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).

`slug()` is an optional function to override the default entry slug generated by Astro. This function receives the `defaultSlug`, entry `id`, unparsed document `body`, and `data` parsed by your configured schema, if any.
[See the `Content Collection` guide](/en/guides/content-collections/#defining-a-collection-schema) for example usage.

### `getCollection()`

Expand Down

0 comments on commit 5bf17de

Please sign in to comment.