System Live
BUILD IN PUBLIC: Updating Neural Engine v2.1.0... | New blog post: Rust for AI optimization... | System Uptime: 99.98% Across All Sectors... | Compiling Archive 404: Logic Integrity 100%... | Deploying Lab Sector Delta: Connectivity Established... | Neural Link: Active... Memory Buffer: Clear... | AI Solver: Processing Complex Engineering Query... | BUILD IN PUBLIC: Updating Neural Engine v2.1.0... | New blog post: Rust for AI optimization... | System Uptime: 99.98% Across All Sectors... | Compiling Archive 404: Logic Integrity 100%... | Deploying Lab Sector Delta: Connectivity Established... | Neural Link: Active... Memory Buffer: Clear... | AI Solver: Processing Complex Engineering Query... |
Home/Blogs/Type-Safe Content Management with Zod and Content Collections

Featured Research

Type-Safe Content Management with Zod and Content Collections

Build a bulletproof content layer using Zod schemas and Content Collections. Learn how type-safety prevents runtime errors and improves developer experience.

Lead Level
schedule3 min read
calendar_todayJan 20, 2026

Type-Safe Content Management

Managing content in modern web applications requires more than just storing markdown files. You need validation, type-safety, and developer experience. That's where Content Collections and Zod shine.

The Problem with Traditional CMS

Traditional content management has several pain points:

  • ❌ Runtime errors from missing fields
  • ❌ No TypeScript auto-completion
  • ❌ Manual type definitions that drift from reality
  • ❌ Complex validation logic scattered across codebase

Enter Content Collections

Content Collections provides a type-safe layer between your content files and application code:

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// content-collections.ts
import { defineCollection, defineConfig } from "@content-collections/core";
import { z } from "zod";

const blog = defineCollection({
  name: "blog",
  directory: "content/blog",
  include: "**/*.mdx",
  schema: (z) => ({
    title: z.string(),
    date: z.coerce.date(),
    excerpt: z.string(),
    tags: z.array(z.string()),
    featured: z.boolean().default(false),
  }),
});

export default defineConfig({
  collections: [blog],
});

Zod Schema Validation

Zod provides runtime validation with excellent TypeScript inference:

typescript
1
2
3
4
5
6
7
8
9
10
11
// Validation at build time
const blogSchema = z.object({
  title: z.string().min(1, "Title required"),
  date: z.coerce.date(),
  tags: z.array(z.string()).min(1),
  excerpt: z.string().max(200),
});

// TypeScript knows the exact type!
type BlogPost = z.infer<typeof blogSchema>;

Advanced Validation

Zod supports complex validation scenarios:

typescript
1
2
3
4
5
6
7
8
9
10
const projectSchema = z.object({
  title: z.string(),
  repoUrl: z.string().url().refine(
    (url) => url.includes('github.com'),
    "Must be a GitHub repository"
  ),
  techStack: z.array(z.string()).min(1).max(10),
  status: z.enum(['active', 'archived', 'planned']),
});

Type-Safe Frontend Components

Once configured, you get 100% type-safe content access:

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// app/blog/page.tsx
import { allBlogs } from "content-collections";

export default function BlogIndex() {
  return (
    <div>
      {allBlogs.map((post) => (
        <article key={post.slug}>
          {/* TypeScript knows all these properties exist! */}
          <h2>{post.title}</h2>
          <time>{post.date.toLocaleDateString()}</time>
          <p>{post.excerpt}</p>
          {post.featured && <span>⭐ Featured</span>}
        </article>
      ))}
    </div>
  );
}

Benefits

1. Catch Errors Early

Schema validation runs at build time, preventing invalid content from reaching production.

2. Perfect TypeScript Integration

No manual type definitions needed - types are inferred from your schemas.

3. Better Developer Experience

Auto-completion, inline documentation, and compile-time error checking.

4. Content Versioning

Schema changes are tracked and can be migrated systematically.

Real-World Example

Here's a complete workflow:

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 1. Define schema
const snippetSchema = z.object({
  title: z.string(),
  language: z.enum(["TS", "Rust", "Python", "Bash"]),
  code: z.string(),
});

// 2. Create content
// content/snippets/async-patterns.json
{
  "title": "Async Patterns in TypeScript",
  "language": "TS",
  "code": "async function fetchData() { ... }"
}

// 3. Use with full type-safety
import { allSnippets } from "content-collections";

const tsSnippets = allSnippets.filter(
  s => s.language === "TS" // TypeScript knows language is the enum!
);

Conclusion

Type-safe content management isn't just a nice-to-have - it's essential for building reliable, maintainable applications. Content Collections + Zod gives you:

✅ Build-time validation
✅ Auto-generated types
✅ Excellent developer experience
✅ Runtime safety

Ready to build something? Check out our Building Modern Web Apps guide!