Skip to content

Commit d3a3d9c

Browse files
committed
Fix TutorialLayout crash for tutorials without optional fields
Add build-time validation via Zod .refine() to enforce that tutorials include authors, featuredImage, featuredImageAlt, and description in production builds while allowing them to be omitted during development. Also add optional chaining in TutorialLayout.astro to prevent crashes when these fields are undefined during dev. Closes #1006
1 parent 2f7b49e commit d3a3d9c

File tree

2 files changed

+35
-17
lines changed

2 files changed

+35
-17
lines changed

src/content/tutorials/config.ts

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,37 @@ export const categories = [
1717
export const tutorialsCollection = defineCollection({
1818
type: "content",
1919
schema: ({ image }) =>
20-
z.object({
21-
// Title of the tutorial
22-
title: z.string(),
23-
// People who wrote the tutorial
24-
authors: z.array(z.string()).optional(),
25-
// Optional note explaining more context about the authors
26-
authorsNote: z.string().optional(),
27-
description: z.string().optional(),
28-
category: z.enum(categories),
29-
categoryIndex: z.number().optional(),
30-
// Image to use as a thumbnail for the tutorial
31-
featuredImage: image().optional(),
32-
featuredImageAlt: z.string().optional(),
33-
relatedContent: relatedContent().optional(),
34-
}),
20+
z
21+
.object({
22+
// Title of the tutorial
23+
title: z.string(),
24+
// People who wrote the tutorial
25+
authors: z.array(z.string()).optional(),
26+
// Optional note explaining more context about the authors
27+
authorsNote: z.string().optional(),
28+
description: z.string().optional(),
29+
category: z.enum(categories),
30+
categoryIndex: z.number().optional(),
31+
// Image to use as a thumbnail for the tutorial
32+
featuredImage: image().optional(),
33+
featuredImageAlt: z.string().optional(),
34+
relatedContent: relatedContent().optional(),
35+
})
36+
.refine(
37+
(data) => {
38+
// Allow missing fields during development for quicker iteration
39+
if (import.meta.env.DEV) return true;
40+
return (
41+
data.authors !== undefined &&
42+
data.authors.length > 0 &&
43+
data.featuredImage !== undefined &&
44+
data.featuredImageAlt !== undefined &&
45+
data.description !== undefined
46+
);
47+
},
48+
{
49+
message:
50+
"Tutorials must include authors, featuredImage, featuredImageAlt, and description for production builds",
51+
},
52+
),
3553
});

src/layouts/TutorialLayout.astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ const { showBanner, englishUrl } = checkTranslationBanner(
5959
<Head
6060
title={entry.data.title}
6161
locale={currentLocale}
62-
description={entry.data.authors.join(", ")}
63-
featuredImageSrc={entry.data.featuredImage.src}
62+
description={entry.data.authors?.join(", ")}
63+
featuredImageSrc={entry.data.featuredImage?.src}
6464
/>
6565

6666
<BaseLayout

0 commit comments

Comments
 (0)