Design-Driven Block Systems: Complete 7-Part Guide

Turn Figma mockups into production-ready Payload CMS block systems—TypeScript types, components, collections, and…

·Matija Žiberna·
Design-Driven Block Systems: Complete 7-Part Guide

📚 Comprehensive Payload CMS Guides

Detailed Payload guides with field configuration examples, custom components, and workflow optimization tips to speed up your CMS development process.

No spam. Unsubscribe anytime.

From Figma mockup to production Payload CMS integration—without refactoring

Welcome to a systematic approach for building block systems and collections where design drives your data structure rather than the other way around. Whether you're new to your project or extending it with new blocks, this guide series will walk you through every scenario.

Why This Matters

Most developers build components like this:

  1. Guess at a data structure
  2. Build the component
  3. Show the designer
  4. Discover the data structure doesn't match
  5. Refactor everything (repeat steps 1-4)

Design-driven development flips the process. You look at Figma, extract the data needs directly, build components that match from day one, and when Payload CMS integration comes, your types already align perfectly.

The result? Zero refactoring. Zero mismatches. Total confidence.


The Guide Series

This is a 7-part journey that builds on itself. Each guide is self-contained, but they connect logically:

1. Design-Driven Development ← Start Here

Philosophy & Mindset | 5 min read

Understand why design comes first. Learn the 5 concrete benefits of this approach. See why Payload integration becomes trivial when you build this way.

Key question answered: Why should I care about design-driven development?


2. Adding Blocks from Payload

Using Existing Types | 10 min read

Payload already has Hero, Services, FeaturedProjects, and other block types. This guide shows you how to:

  • Use Payload types directly in components
  • Build components without creating custom types
  • Create example data for those blocks
  • Integrate blocks into pages

Best for: When you're working with existing Payload block definitions.

Key question answered: How do I use a block that Payload already defined?


3. Creating Custom Block Types

Building From Scratch | 15 min read

Building a new block type from Figma design to component to page integration. This guide walks through:

  • Analyzing Figma design to extract data fields
  • Defining your custom block type
  • Building the component
  • Creating example data
  • Updating BlockRenderer
  • Adding to pages

Best for: When Payload doesn't have the block you need yet.

Real example: Building a "Featured Industries" block from design mockup to rendered page.

Key question answered: How do I build a completely new block?


4. Creating Collections

Data Entities & Reusable Data | 10 min read

Collections are reusable data entities (Industry, Client, Product, Team Member) that appear across multiple blocks. This guide shows:

  • Defining collection types from design
  • Creating example collections
  • Using collections in multiple blocks
  • Structure for Payload CMS integration

Best for: When you have data that multiple blocks need to reference.

Real example: Industry collection used by FeaturedIndustries block, IndustryGrid block, and other places.

Key question answered: How do I create reusable data that multiple blocks share?


5. Icons, Components & Reusable Types

Consistency & Best Practices | 12 min read

Three critical practices ensure consistency across your entire system:

  1. Lucide React for icons - Icon naming conventions, usage patterns
  2. shadcn/ui for components - When to use shadcn/ui, what not to build custom
  3. Global CTA type - Using the same CTA structure everywhere

Best for: Understanding standards and consistency practices.

Key question answered: How do I keep all blocks consistent and maintainable?


6. Quick Reference: Templates & Checklists

Copy-Paste Resources | Reference

Tired of remembering syntax? This section contains:

  • Type definition template - Copy-paste structure for new types
  • Component template - Component boilerplate
  • Example data template - How to structure examples
  • Page data template - Adding blocks to pages
  • BlockRenderer addition template - How to add block routing
  • Pre-flight checklists - Don't forget anything

Best for: When you're actively building and need quick templates.

Key question answered: What's the exact format I should use for [type/component/data]?


7. Migration to Payload CMS

From Manual Types to Real CMS | 8 min read

The magical moment: you built everything with manual example data, and now you're ready for Payload CMS. This guide shows:

  • How to generate Payload config from your types
  • Changing data sources without touching components
  • Query patterns for fetching from Payload
  • Handling draft vs published states
  • Migrating existing example data

The magic reveal: Your components don't change. Your types don't change. Only the import source changes. That's it.

Best for: When you're ready to integrate with a real Payload CMS instance.

Key question answered: How do I move from example data to real Payload CMS data?


Quick Navigation

I want to...

GoalRead This
Understand the entire philosophyEpisode 1: Design-Driven Development
Use an existing Payload block typeEpisode 2: Adding Blocks from Payload
Create a completely new blockEpisode 3: Creating Custom Block Types
Build reusable data (Industry, Client, etc.)Episode 4: Creating Collections
Understand consistency standardsEpisode 5: Icons, Components & Reusable Types
Get copy-paste templatesEpisode 6: Quick Reference
Integrate with Payload CMSEpisode 7: Migration to Payload CMS

The Complete Development Flow

Here's how everything connects in a real project:

DESIGN PHASE
   ↓
   Designer creates Figma mockup for new feature
   ↓
ANALYZE PHASE
   ↓
   You open Figma and identify data fields
   ↓
   Question: "Does Payload already have this block type?"
   ├─ YES → Read Episode 2 (Using Existing Types)
   └─ NO  → Read Episode 3 (Creating Custom Types)
   ↓
IMPLEMENT PHASE
   ↓
   You create types, components, example data
   ├─ Need icons? → Episode 5
   ├─ Need templates? → Episode 6
   └─ Need components? → Episode 5
   ↓
EXAMPLE DATA PHASE
   ↓
   Add data to app/data.ts, render with BlockRenderer
   Feature is complete and looks exactly like design
   ↓
PAYLOAD INTEGRATION PHASE (Later)
   ↓
   Ready to connect to real CMS?
   → Read Episode 7 (Migration to Payload CMS)
   Change import source, everything works
   ↓
COMPLETE ✓
   Feature is live from Payload CMS
   No refactoring needed
   Zero mismatch with design

Key Principles

These principles run through every guide:

1. Design is Your Specification

Don't guess. Look at Figma. The design shows you exactly what data you need.

2. Types Mirror Design

Your TypeScript types should directly reflect what Figma shows. One-to-one mapping.

3. Components Are Dumb

Components don't decide what data exists. They display what types tell them to display.

4. Reuse Global Types

CTA, Image, Button—use them everywhere. One type change fixes the entire app.

5. Example Data is Your Documentation

Before Payload, example data IS your spec. Later, Payload replaces it (components stay the same).

6. No Refactoring on CMS Integration

Your component code doesn't change when you switch from example data to Payload. Only the import source changes.


Project Structure (What You'll Be Building)

project-root/
├── payload-types.ts                    ← Source of truth
│
├── app/
│   ├── page.tsx                        ← Homepage
│   ├── data.ts                         ← All page data lives here
│   ├── about/
│   │   ├── page.tsx
│   │   └── data.ts
│   └── [other pages]/
│
└── src/components/
    ├── block-renderer.tsx              ← Routes blocks to components
    └── blocks/
        ├── hero/
        │   ├── hero-template-1.tsx
        │   └── index.ts
        ├── featured-industries/
        │   ├── featured-industries-template-1.tsx
        │   └── index.ts
        ├── services/
        │   ├── services-template-1.tsx
        │   └── index.ts
        └── [your new blocks]/

Before You Start

Make sure you have:

  • Familiarity with Next.js and TypeScript
  • Access to your project codebase
  • Figma design for what you're building
  • Understanding of your data structure (what fields do you need?)

Not comfortable with one of these? No problem. Start with Episode 1, work through the real examples, and you'll pick it up fast.


How to Use These Guides

If you're new to the project:

  1. Read Episode 1 (Philosophy) to understand the approach
  2. Pick the scenario that matches your task:
    • Using existing block? → Episode 2
    • Creating new block? → Episode 3
    • Need templates? → Episode 6
  3. Follow the step-by-step instructions
  4. Use Episode 6 for copy-paste templates when needed

If you're extending the project:

  1. Identify: What am I building? (block, collection, page?)
  2. Jump to the relevant episode
  3. Use Episode 6 for templates
  4. Reference Episode 5 for consistency standards

If you're integrating Payload CMS:

  1. Build everything with example data first (Episodes 2-6)
  2. When ready to connect Payload, read Episode 7
  3. Change import, everything works

Common Scenarios & Solutions

ScenarioRead This
I need to add a Hero block to the homepageEpisode 2 + Episode 6
I need to create a new block type that doesn't existEpisode 3
I need a reusable list of IndustriesEpisode 4
I'm confused about Lucide icons vs shadcn/ui componentsEpisode 5
I'm building a block but can't remember the exact syntaxEpisode 6
I have example data and now need to connect PayloadEpisode 7

Questions & Feedback

These guides are living documents. They improve when you ask questions:

  1. Confused about something? → Check the specific episode
  2. Need templates? → Episode 6: Quick Reference
  3. Want to see real code? → Check src/types/ and src/components/blocks/ in the project
  4. Want clarification? → Ask the team—these guides improve with your feedback

The Big Picture

You're learning a systematic approach that:

  • Prevents refactoring
  • Keeps design and code aligned
  • Makes CMS integration trivial
  • Ensures consistency across your entire codebase
  • Lets you ship faster

This isn't theoretical. It's a proven pattern used in production systems that scale.

0

Frequently Asked Questions

Comments

Leave a Comment

Your email will not be published

10-2000 characters

• Comments are automatically approved and will appear immediately

• Your name and email will be saved for future comments

• Be respectful and constructive in your feedback

• No spam, self-promotion, or off-topic content

Matija Žiberna
Matija Žiberna
Full-stack developer, co-founder

I'm Matija Žiberna, a self-taught full-stack developer and co-founder passionate about building products, writing clean code, and figuring out how to turn ideas into businesses. I write about web development with Next.js, lessons from entrepreneurship, and the journey of learning by doing. My goal is to provide value through code—whether it's through tools, content, or real-world software.