Skip to content

Commit 712202e

Browse files
authored
Migrate content collections to all use loaders (#1964)
1 parent 00d8ee8 commit 712202e

File tree

12 files changed

+40
-28
lines changed

12 files changed

+40
-28
lines changed

src/content/config.ts renamed to src/content.config.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defineCollection } from 'astro:content';
22
import { file, glob } from 'astro/loaders';
33
import { z } from 'astro/zod';
4-
import authors from '../data/authors/authors.json';
4+
import authors from './data/authors/authors.json';
55

66
export const IntegrationCategories = new Map([
77
['recent', 'Recently Added'],
@@ -53,6 +53,7 @@ export const collections = {
5353
.strict(),
5454
}),
5555
blog: defineCollection({
56+
loader: glob({ base: './src/content/blog', pattern: '*.mdx' }),
5657
schema: z.object({
5758
title: z.string().describe('The blog post title.'),
5859
description: z
@@ -101,6 +102,7 @@ export const collections = {
101102
}),
102103
}),
103104
caseStudies: defineCollection({
105+
loader: glob({ base: './src/content/caseStudies', pattern: '*.mdx' }),
104106
schema: z
105107
.object({
106108
seo: seoSchema.optional(),
@@ -119,6 +121,7 @@ export const collections = {
119121
.transform((study) => ({ ...study, isCaseStudy: true })),
120122
}),
121123
integrations: {
124+
loader: glob({ base: './src/content/integrations', pattern: '*.md' }),
122125
schema: z.object({
123126
name: z.string().describe('Name of the package as it is published to NPM'),
124127
title: z
@@ -140,6 +143,7 @@ export const collections = {
140143
}),
141144
},
142145
pages: defineCollection({
146+
loader: glob({ base: './src/content/pages', pattern: '**/*.md' }),
143147
schema: ({ image }) =>
144148
z.discriminatedUnion('pageLayout', [
145149
z.object({
@@ -157,9 +161,11 @@ export const collections = {
157161
]),
158162
}),
159163
partials: {
164+
loader: glob({ base: './src/content/partials', pattern: '*.md' }),
160165
schema: z.object({}),
161166
},
162167
quotes: {
168+
loader: glob({ base: './src/content/quotes', pattern: '*.md' }),
163169
schema: z.object({
164170
author: z.object({
165171
handle: z.string(),
@@ -173,7 +179,13 @@ export const collections = {
173179
}),
174180
},
175181
showcase: defineCollection({
176-
type: 'data',
182+
loader: glob({
183+
base: './src/content/showcase',
184+
pattern: '*.yml',
185+
// Showcase filenames are based on the site URL, and we don’t want Astro to strip out periods,
186+
// so we just remove the file extension and otherwise do nothing.
187+
generateId: ({ entry }) => entry.split('.').slice(0, -1).join('.'),
188+
}),
177189
schema: ({ image }) =>
178190
z.object({
179191
title: z

src/helpers/integrations.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { type CollectionEntry, getCollection } from 'astro:content';
2-
import { IntegrationCategories } from '~/content/config.js';
2+
import { IntegrationCategories } from '~/content.config.js';
33
import type { MapKeys } from './types.ts';
44

55
interface IntegrationOptions {

src/pages/[...slug].astro

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
---
22
import { Image } from 'astro:assets';
3-
import { type CollectionEntry, getCollection } from 'astro:content';
3+
import { type CollectionEntry, getCollection, render } from 'astro:content';
44
import MainLayout from '~/layouts/MainLayout.astro';
55
66
export async function getStaticPaths() {
77
const pages = await getCollection('pages');
88
99
return pages.map((page) => {
1010
return {
11-
params: { slug: page.slug },
11+
params: { slug: page.id },
1212
props: { page },
1313
};
1414
});
1515
}
1616
1717
const { page } = Astro.props as { page: CollectionEntry<'pages'> };
1818
const { seo, pageLayout } = page.data;
19-
const { Content } = await page.render();
19+
const { Content } = await render(page);
2020
---
2121

2222
<MainLayout {...seo}>

src/pages/_components/LatestBlogPostLink.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const latestBlogPost = blogPostsWithBanner
1313
{
1414
latestBlogPost && (
1515
<PillLink
16-
href={`/blog/${latestBlogPost.slug}/`}
16+
href={`/blog/${latestBlogPost.id}/`}
1717
title={latestBlogPost.data.homepageLink!.title}
1818
subtitle={latestBlogPost.data.homepageLink!.subtitle}
1919
/>

src/pages/blog/[...page].astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const featuredPosts = [
3535
'netlify-official-deployment-partner',
3636
'2023-web-framework-performance-report',
3737
]
38-
.map((slug) => allPosts.find((post) => post.slug === slug))
38+
.map((slug) => allPosts.find((post) => post.id === slug))
3939
.filter(Boolean) as CollectionEntry<'blog'>[];
4040
---
4141

@@ -65,7 +65,7 @@ const featuredPosts = [
6565
<li>
6666
<a
6767
class="body link-underline border-astro-pink-light text-lg text-astro-pink-light"
68-
href={`/blog/${post.slug}/`}
68+
href={`/blog/${post.id}/`}
6969
data-astro-prefetch
7070
>
7171
{post?.data.title}

src/pages/blog/[slug].astro

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
import { Image } from 'astro:assets';
3-
import { type CollectionEntry, getCollection, getEntry } from 'astro:content';
3+
import { type CollectionEntry, getCollection, getEntry, render } from 'astro:content';
44
import { format } from 'date-fns';
55
import Avatar from '~/components/Avatar.astro';
66
import { resolveCoverImage, resolveSocialImage } from '~/content/blog/_resolveImage.js';
@@ -17,15 +17,15 @@ export async function getStaticPaths() {
1717
const blog = await getCollection('blog');
1818
1919
return blog.map((post) => ({
20-
params: { slug: post.slug },
20+
params: { slug: post.id },
2121
props: { post },
2222
}));
2323
}
2424
2525
const { post } = Astro.props;
2626
27-
const { data, render } = post;
28-
const { Content } = await render();
27+
const { data } = post;
28+
const { Content } = await render(post);
2929
3030
const coverImage = await resolveCoverImage(post);
3131
const socialImage = await resolveSocialImage(post);

src/pages/blog/_components/BlogLinkCard.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const base = post.collection === 'caseStudies' ? 'case-studies' : 'blog';
2424
{image && <Image src={image} alt="" width="1000" />}
2525
<div class="px-4 py-6 flex flex-col gap-4">
2626
<a
27-
href={`/${base}/${post.slug}/`}
27+
href={`/${base}/${post.id}/`}
2828
class="text-pretty heading-4 md:heading-3 text-white no-underline outline-none after:absolute after:inset-0"
2929
>
3030
{post.data.title}

src/pages/blog/_components/BlogPostPreview.astro

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { resolveCoverImage } from '~/content/blog/_resolveImage.js';
66
export type Props = {
77
isCaseStudy: boolean;
88
post: {
9-
slug: string;
9+
id: string;
1010
data: {
1111
title: string;
1212
description: string;
@@ -24,7 +24,7 @@ const image = await resolveCoverImage(post);
2424

2525
<article
2626
class="relative border border-astro-gray-500 bg-astro-gray-600 p-4 outline-astro-pink-light transition-transform duration-300 ease-out focus-within:outline hover:scale-[1.03]"
27-
aria-labelledby={post.slug}
27+
aria-labelledby={post.id}
2828
>
2929
<header>
3030
<time class="code text-astro-gray-200" datetime={post.data.publishDate.toISOString()}>
@@ -48,9 +48,9 @@ const image = await resolveCoverImage(post);
4848
</div>
4949

5050
<div class="mt-6 grid gap-x-16 gap-y-4 md:grid-cols-2">
51-
<h3 class="heading-4 md:heading-3" id={post.slug}>
51+
<h3 class="heading-4 md:heading-3" id={post.id}>
5252
<a
53-
href={isCaseStudy ? `/case-studies/${post.slug}/` : `/blog/${post.slug}/`}
53+
href={isCaseStudy ? `/case-studies/${post.id}/` : `/blog/${post.id}/`}
5454
data-astro-prefetch
5555
class="outline-none after:absolute after:inset-0"
5656
>

src/pages/case-studies/[slug].astro

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
import { Image } from 'astro:assets';
3-
import { type CollectionEntry, getCollection, getEntry } from 'astro:content';
3+
import { type CollectionEntry, getCollection, getEntry, render } from 'astro:content';
44
import { format } from 'date-fns';
55
import houstonWink from '~/assets/houston_wink.webp';
66
import Avatar from '~/components/Avatar.astro';
@@ -14,15 +14,15 @@ export type Props = {
1414
export async function getStaticPaths() {
1515
const items = await getCollection('caseStudies');
1616
return items.map((post) => ({
17-
params: { slug: post.slug },
17+
params: { slug: post.id },
1818
props: { post },
1919
}));
2020
}
2121
2222
const { post } = Astro.props;
2323
24-
const { data, render } = post;
25-
const { Content } = await render();
24+
const { data } = post;
25+
const { Content } = await render(post);
2626
2727
const socialImage = await resolveSocialImage(post);
2828

src/pages/case-studies/_components/CaseStudyCard.astro

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { resolveCoverImage } from '~/content/blog/_resolveImage.js';
44
55
export type Props = {
66
post: {
7-
slug: string;
7+
id: string;
88
data: {
99
title: string;
1010
description: string;
@@ -21,7 +21,7 @@ const image = await resolveCoverImage(post);
2121

2222
<article
2323
class="relative border border-astro-gray-500 bg-astro-gray-600 p-4 pt-0 outline-astro-pink-light transition-transform duration-300 ease-out focus-within:outline hover:scale-[1.03]"
24-
aria-labelledby={post.slug}
24+
aria-labelledby={post.id}
2525
>
2626
<div class="-mx-4">
2727
{
@@ -39,9 +39,9 @@ const image = await resolveCoverImage(post);
3939
</div>
4040

4141
<div class="mt-6 flex flex-col gap-x-16 gap-y-4">
42-
<h2 class="heading-4 md:heading-3" id={post.slug}>
42+
<h2 class="heading-4 md:heading-3" id={post.id}>
4343
<a
44-
href={`/case-studies/${post.slug}/`}
44+
href={`/case-studies/${post.id}/`}
4545
data-astro-prefetch
4646
class="outline-none after:absolute after:inset-0"
4747
>

0 commit comments

Comments
 (0)