---
title: "Block Component Templates: Quick Reference & Checklists"
slug: "block-component-templates-checklists"
published: "2025-11-20"
updated: "2025-11-12"
validated: "2025-11-12"
categories:
  - "React"
tags:
  - "block component templates"
  - "React component templates"
  - "TypeScript block types"
  - "Tailwind UI patterns"
  - "shadcn/ui templates"
  - "BlockRenderer integration"
  - "collection type template"
  - "example data for blocks"
  - "block creation checklist"
  - "integration checklist"
  - "Lucide icons"
llm-intent: "reference"
audience-level: "intermediate"
framework-versions:
  - "typescript"
  - "react"
  - "tailwind css"
  - "shadcn/ui"
  - "lucide"
status: "stable"
llm-purpose: "Block component templates: ready TypeScript + React templates, example data, and checklists to build blocks, collections and integrate with…"
llm-prereqs:
  - "Access to TypeScript"
  - "Access to React"
  - "Access to Tailwind CSS"
  - "Access to shadcn/ui"
  - "Access to Lucide"
llm-outputs:
  - "Completed outcome: Block component templates: ready TypeScript + React templates, example data, and checklists to build blocks, collections and integrate with…"
---

**Summary Triples**
- (Block Type File, location, src/types/blocks/[block-name].ts)
- (Block Type File, mustContain, interface with id?, blockType, template, content fields, items array)
- (React Block Component, location, src/components/blocks/[name]/[name]-template-1.tsx)
- (React Block Component, shouldExport, function component accepting typed props (data: [BlockName]Block))
- (Default Props, recommended, destructure with defaults (e.g., items = [], bgColor = 'white') to avoid runtime errors)
- (Styling, use, Tailwind utility classes with a bgClass mapping for bgColor variants)
- (Icons & Media, use, lucide-react for icons and Payload Media type (or next/image) for images)
- (Integration, require, matching blockType strings across type, component, and CMS/BlockRenderer registration)
- (Example Data, purpose, seed Storybook, tests and CMS previews to validate layout and edge cases)
- (Checklist, covers, type definition, component implementation, accessibility, responsive testing and CMS wiring)

### {GOAL}
Block component templates: ready TypeScript + React templates, example data, and checklists to build blocks, collections and integrate with…

### {PREREQS}
- Access to TypeScript
- Access to React
- Access to Tailwind CSS
- Access to shadcn/ui
- Access to Lucide

### {STEPS}
1. Create block type definition
2. Implement block component template
3. Add example data file
4. Define collection type and examples
5. Register block in BlockRenderer
6. Include block in page data
7. Run the integration checklist
8. Troubleshoot common issues

<!-- llm:goal="Block component templates: ready TypeScript + React templates, example data, and checklists to build blocks, collections and integrate with…" -->
<!-- llm:prereq="Access to TypeScript" -->
<!-- llm:prereq="Access to React" -->
<!-- llm:prereq="Access to Tailwind CSS" -->
<!-- llm:prereq="Access to shadcn/ui" -->
<!-- llm:prereq="Access to Lucide" -->
<!-- llm:output="Completed outcome: Block component templates: ready TypeScript + React templates, example data, and checklists to build blocks, collections and integrate with…" -->

# Block Component Templates: Quick Reference & Checklists
> Block component templates: ready TypeScript + React templates, example data, and checklists to build blocks, collections and integrate with…
Matija Žiberna · 2025-11-20

> Part 6 of the [Design to Code](/blog/design-driven-block-systems) series — Following [Icons, Components & Reusable Types](/blog/lucide-react-shadcn-ui-cta-best-practices)

This is a reference page with copy-paste templates and checklists. When you're building a block or collection, come here to grab the template that matches your scenario.

## Copy-Paste Templates

### Template: Block Type Definition

File: `src/types/blocks/[block-name].ts`

```typescript
import type { Media } from '@payload-types';
import type { CTA } from '@/types/blocks';

/**
 * [BlockName] Block
 * [Brief description of what this block displays]
 */
export interface [BlockName]Block {
  // Identification
  id?: string;
  blockType: '[blockName]';
  template: 'default' | 'variant1';

  // Content
  tagline?: string;
  title?: string;
  description?: string;

  // Data
  items?: [Item][];

  // Styling
  bgColor?: 'white' | 'light' | 'dark';
}

export interface [Item] {
  id: string | number;
  title: string;
  description?: string;
  icon?: string;
  image?: Media;
  cta?: CTA;
}
```

Replace:
- `[BlockName]` with your block name (FeaturedIndustries, Testimonials, etc.)
- `[blockName]` with camelCase version
- `[Item]` with your item type (Industry, Testimonial, etc.)
- Fields based on your Figma design

---

### Template: Block Component

File: `src/components/blocks/[name]/[name]-template-1.tsx`

```typescript
'use client';

import type { [BlockName]Block } from '@/types/blocks';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';

interface [BlockName]Template1Props {
  data: [BlockName]Block;
}

export function [BlockName]Template1({ data }: [BlockName]Template1Props) {
  const {
    tagline,
    title,
    description,
    items = [],
    bgColor = 'white',
  } = data;

  const bgClass = {
    white: 'bg-white',
    light: 'bg-gray-50',
    dark: 'bg-gray-900',
  }[bgColor];

  return (
    <section className={`py-24 ${bgClass}`}>
      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
        {/* Header */}
        {tagline && (
          <p className="text-sm font-semibold text-blue-600 uppercase tracking-widest mb-2">
            {tagline}
          </p>
        )}
        {title && (
          <h2 className="text-4xl font-bold mb-4">
            {title}
          </h2>
        )}
        {description && (
          <p className="text-xl text-gray-600 mb-12 max-w-2xl">
            {description}
          </p>
        )}

        {/* Items Grid */}
        <div className="grid grid-cols-1 md:grid-cols-3 gap-8">
          {items.map((item) => (
            <Card key={item.id}>
              <CardHeader>
                <CardTitle>{item.title}</CardTitle>
              </CardHeader>
              <CardContent>
                {item.description && <p className="text-gray-600">{item.description}</p>}
              </CardContent>
            </Card>
          ))}
        </div>

        {/* Empty State */}
        {items.length === 0 && (
          <div className="text-center py-12 text-gray-500">
            <p>No items to display</p>
          </div>
        )}
      </div>
    </section>
  );
}
```

Replace:
- `[BlockName]` with your component/type name
- Grid columns: adjust `md:grid-cols-3` based on design
- Card content: add fields from your type

---

### Template: Example Data

File: `src/components/blocks/[name]/[name].example.ts`

```typescript
import type { [BlockName]Block, [Item] } from '@/types/blocks';

const item1: [Item] = {
  id: 1,
  title: 'Item Title',
  description: 'Item description',
  icon: 'Star',
};

const item2: [Item] = {
  id: 2,
  title: 'Another Item',
  description: 'Description',
  icon: 'Heart',
};

export const [blockName]Example: [BlockName]Block = {
  blockType: '[blockName]',
  template: 'default',
  tagline: 'Section Label',
  title: 'Main Heading',
  description: 'Subtitle or description',
  items: [item1, item2],
  bgColor: 'light',
};
```

---

### Template: Collection Type

File: `src/types/collections/[name].ts`

```typescript
import type { Media } from '@payload-types';
import type { CTA } from '@/types/blocks';

/**
 * [Collection Name] Collection
 * [Description of what this entity represents]
 */
export interface [CollectionName] {
  // Core
  id: number;
  title: string;
  slug?: string;

  // Content
  description?: string;
  longDescription?: string;

  // Media
  image?: Media;
  icon?: string;

  // Link
  link?: CTA;

  // Status
  _status?: 'draft' | 'published';
  meta?: {
    title?: string;
    description?: string;
  };

  // Timestamps
  createdAt: string;
  updatedAt: string;
}

// Example item
export const [collectionNameExample]: [CollectionName] = {
  id: 1,
  title: 'Example Item',
  slug: 'example-item',
  description: 'Description of the item',
  image: {
    url: 'https://example.com/image.jpg',
    alt: 'Image alt text',
  },
  icon: 'Star',
  link: {
    label: 'Learn More',
    href: '/example',
  },
  _status: 'published',
  createdAt: new Date().toISOString(),
  updatedAt: new Date().toISOString(),
};

export const [collectionNamePluralData]: [CollectionName][] = [
  [collectionNameExample],
  // Add more examples
];
```

---

### Template: BlockRenderer Update

File: `src/components/block-renderer.tsx`

```typescript
import { [BlockName]Template1 } from '@/components/blocks/[name]';

export function BlockRenderer({ block }: BlockRendererProps) {
  // ... existing blocks ...

  if (block.blockType === '[blockName]') {
    if (block.template === 'default') {
      return <[BlockName]Template1 data={block as any} />;
    }
  }

  console.warn(`Unknown block: ${block.blockType}/${block.template}`);
  return null;
}
```

---

### Template: Page Data

File: `src/app/data.ts`

```typescript
import type { Page } from '@payload-types';
import { [blockName]Example } from '@/components/blocks/[name]/[name].example';

export const homePageData: Page = {
  id: 'home',
  slug: '/',
  title: 'Home',
  layout: [
    {
      blockType: '[blockName]',
      template: 'default',
      title: 'Your Title',
      items: [/* your items */],
    } as [BlockName]Block,
  ],
};
```

---

## Checklists

### Creating a New Block Type

```
NEW BLOCK CREATION CHECKLIST:

SETUP
□ Created src/types/blocks/[name].ts with type definition
□ Exported from src/types/blocks/index.ts
□ Created interface for items (if needed)

COMPONENT
□ Created src/components/blocks/[name]/[name]-template-1.tsx
□ Imported type from @/types/blocks
□ Used shadcn/ui components (Button, Card, etc.)
□ Customized styling with Tailwind className
□ Handled empty state gracefully

EXAMPLES & DATA
□ Created src/components/blocks/[name]/[name].example.ts
□ Example data matches type exactly
□ Created array of examples (for collections)

INTEGRATION
□ Updated src/components/block-renderer.tsx
□ Added case for blockType
□ Added all template variations
□ Tested component renders without errors

TESTING
□ Added to src/app/data.ts
□ Component renders on page
□ Styling matches Figma design
□ Icons use Lucide (not SVG imports)
□ Buttons use CTA type
□ No TypeScript errors
```

### Creating a New Collection

```
COLLECTION CREATION CHECKLIST:

SETUP
□ Created src/types/collections/[name].ts
□ Defined interface with all needed fields
□ Used sensible default values for optional fields

EXAMPLES
□ Created example instances of the collection
□ Created array (Plural)Data with multiple examples
□ Example data matches interface exactly
□ Used realistic values for each field

EXPORT
□ Exported type from src/types/collections/index.ts
□ Exported example data from index
□ Verified imports work in blocks

USAGE
□ Used collection type in block type definition
□ Block component correctly displays collection items
□ Page data correctly passes collection array to block
□ No TypeScript errors
```

### Integration Checklist

```
INTEGRATION CHECKLIST:

TYPES
□ Type imports from correct location (@payload-types or @/types/blocks)
□ All required fields present in example data
□ Optional fields clearly marked with `?:`
□ Fields match Figma design

COMPONENTS
□ Component receives correct type prop
□ Component destructures needed fields
□ Uses shadcn/ui for generic UI
□ Uses Lucide for icons
□ No custom component recreation
□ Proper TypeScript types (no `any` type assertions)

STYLING
□ Colors match Figma (use Tailwind or inline styles)
□ Spacing matches Figma (padding, margins, gaps)
□ Responsive breakpoints work correctly
□ Hover states and transitions feel smooth
□ Dark mode (if needed) works correctly

FUNCTIONALITY
□ Interactive elements work (buttons, links)
□ Icons display correctly
□ Empty states handled gracefully
□ No console errors
□ No warnings
```

---

## Quick Lookup

### I need to...

| Need | Template |
|------|----------|
| Define a new block type | [Block Type Definition](#template-block-type-definition) |
| Build a block component | [Block Component](#template-block-component) |
| Create example block data | [Example Data](#template-example-data) |
| Define a new collection | [Collection Type](#template-collection-type) |
| Add block to BlockRenderer | [BlockRenderer Update](#template-blockrenderer-update) |
| Add block to page | [Page Data](#template-page-data) |

### Icons to Use

Common icon mappings:

```typescript
const iconMap = {
  'Zap': Zap,           // Fast, energy
  'Heart': Heart,       // Love, care
  'Star': Star,         // Quality, featured
  'ShoppingBag': ShoppingBag,  // Shopping, retail
  'Briefcase': Briefcase,      // Business, work
  'Mail': Mail,         // Contact, email
  'Phone': Phone,       // Contact, phone
  'MapPin': MapPin,     // Location
  'ArrowRight': ArrowRight,    // Next, forward
  'Check': Check,       // Done, complete
};
```

Full list at [lucide.dev](https://lucide.dev)

### Styling Utilities

Common Tailwind patterns:

```typescript
// Section padding
className="py-24"  // Vertical padding
className="px-4 sm:px-6 lg:px-8"  // Responsive horizontal

// Typography
className="text-4xl font-bold"  // Large heading
className="text-xl text-gray-600"  // Subtitle
className="text-sm font-semibold uppercase"  // Label

// Grid layouts
className="grid grid-cols-1 md:grid-cols-3 gap-8"  // 1 col mobile, 3 cols desktop
className="grid grid-cols-2 lg:grid-cols-4 gap-6"  // 2 cols tablet, 4 cols desktop

// Cards & Containers
className="max-w-7xl mx-auto"  // Centered container with max width
className="rounded-lg shadow-lg"  // Border radius + shadow
className="hover:shadow-lg transition-shadow"  // Hover effect

// Backgrounds
className="bg-white"
className="bg-gray-50"
className="bg-gray-900"
```

---

## When You're Stuck

1. **Type error?** Check that you're importing from the right location (@/types/blocks vs @payload-types)
2. **Component not rendering?** Verify BlockRenderer has the correct case for your blockType
3. **Styling doesn't match?** Use browser dev tools to see what's applied; override with more specific Tailwind classes
4. **Icon not showing?** Make sure it's in iconMap and spelled correctly
5. **TypeScript errors?** Hover over the error; usually it's a missing field or wrong type

## LLM Response Snippet
```json
{
  "goal": "Block component templates: ready TypeScript + React templates, example data, and checklists to build blocks, collections and integrate with…",
  "responses": [
    {
      "question": "What does the article \"Block Component Templates: Quick Reference & Checklists\" cover?",
      "answer": "Block component templates: ready TypeScript + React templates, example data, and checklists to build blocks, collections and integrate with…"
    }
  ]
}
```