DEV Community

Zaid Rehman
Zaid Rehman

Posted on

Using Blocks in Sections

Introduction:

Welcome to the third tutorial in the Fynd Platform Theme Development series. In this session, we will focus on blocks, a crucial part of building modular, reusable, and customizable theme sections. By the end of this tutorial, you’ll understand how to define blocks, use them in sections, and leverage their capabilities to create dynamic and merchant-configurable content.

1. What Are Blocks?

Blocks represent individual configurable units within a section. A section can contain multiple blocks, each with its own properties. For example:

  • A banner section might contain blocks for images and captions.
  • A product slider section might have blocks for each product card.

Blocks are defined in the settings.blocks array of a section's configuration file.

2. Anatomy of a Block

Each block consists of:

  • label: Describes the block in the theme editor.
  • type: Specifies the block type (e.g., image, text, range).
  • props: Contains the configurable properties of the block.

Example block configuration:

blocks: [
    {
        label: "Image Card",
        type: "gallery",
        props: [
            {
                id: "image_url",
                label: "Image URL",
                type: "image_picker",
                default: "",
                info: "Upload or select an image for this card."
            },
            {
                id: "alt_text",
                label: "Alt Text",
                type: "text",
                default: "Alt Text",
                info: "Text describing the image for accessibility."
            },
            {
                id: "caption",
                label: "Caption",
                type: "text",
                default: "Enter caption here",
                info: "Caption displayed below the image."
            }
        ]
    }
]
Enter fullscreen mode Exit fullscreen mode

3. Using Blocks in a Section

To use blocks in a section:

Define Blocks in the Section Settings
Add the blocks configuration in the settings object of your section:

export const settings = {
    label: "Image Gallery",
    blocks: [
        {
            label: "Image Card",
            type: "gallery",
            props: [
                {
                    id: "url",
                    label: "Image URL",
                    type: "image_picker",
                    default: "",
                    info: "Upload an image."
                },
                {
                    id: "caption",
                    label: "Caption",
                    type: "text",
                    default: "Default Caption",
                    info: "Caption for the image."
                }
            ]
        }
    ],
    props: [],
};
Enter fullscreen mode Exit fullscreen mode

Access Blocks in the Component
Use the blocks prop passed to the section's component to render block data:

import React from "react";

export function Component({ blocks }) {
    if (!blocks || blocks.length === 0) return null;

    return (
        <div className="image-gallery">
            {blocks.map((block, index) => (
                <div key={index} className="image-card">
                    <img src={block.props.url.value} alt={block.props.caption.value} />
                    <p>{block.props.caption.value}</p>
                </div>
            ))}
        </div>
    );
}
Enter fullscreen mode Exit fullscreen mode

4. Advanced Block Features

Default Values
Default values ensure blocks have initial data when no input is provided. For example:

props: [
    {
        id: "heading",
        label: "Heading",
        type: "text",
        default: "Welcome to our Store",
        info: "Text displayed as the section heading."
    }
]
Enter fullscreen mode Exit fullscreen mode

Multiple Block Types
A section can define multiple block types:

blocks: [
    {
        label: "Banner",
        type: "banner",
        [/* ... */]
    },
    {
        label: "Product Card",
        type: "product",
        [/* ... */]
    }
]
Enter fullscreen mode Exit fullscreen mode

5. Real-Life Use Cases

Banner Section with Multiple Slides

Each slide is represented as a block with properties like image, title, and link.

Settings:

blocks: [
    {
        label: "Slide",
        type: "slide",
        props: [
            {
                id: "image",
                label: "Image",
                type: "image_picker",
                default: "",
                info: "Upload an image for the slide."
            },
            {
                id: "title",
                label: "Title",
                type: "text",
                default: "",
                info: "Title displayed on the slide."
            },
            {
                id: "link",
                label: "Link",
                type: "url",
                default: "",
                info: "URL to navigate when the slide is clicked."
            }
        ]
    }
]

Enter fullscreen mode Exit fullscreen mode

Rendering:

export function Component({ blocks }) {
    return (
        <div className="banner-carousel">
            {blocks.map((block, index) => (
                <div key={index} className="slide">
                    <img src={block.props.image.value} alt={block.props.title.value} />
                    <h3>{block.props.title.value}</h3>
                    <a href={block.props.link.value}>Learn More</a>
                </div>
            ))}
        </div>
    );
}
Enter fullscreen mode Exit fullscreen mode

Product Grid with Configurable Items

Each product is a block containing properties like image, name, and price.

Settings:

blocks: [
    {
        label: "Product",
        type: "product",
        props: [
            { id: "image", label: "Image", type: "image_picker", default: "" },
            { id: "name", label: "Name", type: "text", default: "" },
            { id: "price", label: "Price", type: "text", default: "" }
        ]
    }
]
Enter fullscreen mode Exit fullscreen mode

Rendering:

export function Component({ blocks }) {
    return (
        <div className="product-grid">
            {blocks.map((block, index) => (
                <div key={index} className="product-card">
                    <img src={block.props.image.value} alt={block.props.name.value} />
                    <h4>{block.props.name.value}</h4>
                    <p>${block.props.price.value}</p>
                </div>
            ))}
        </div>
    );
}
Enter fullscreen mode Exit fullscreen mode

6. Best Practices

  • Keep Blocks Modular: Define distinct block types for different use cases.
  • Optimize for Reusability: Use generic and reusable block settings to minimize redundancy.
  • Use Defaults Smartly: Always set meaningful default values to enhance the out-of-box experience.
  • Validate Inputs: Ensure inputs are validated to avoid errors during rendering.

Conclusion:

Blocks are powerful tools for creating dynamic and customizable themes on the Fynd Platform. By leveraging blocks, you can build modular sections that offer a high degree of flexibility for merchants. Experiment with different block configurations to explore their full potential.

In the next tutorial, we’ll dive into global configurations to manage theme-level settings. See you there!

Top comments (0)