Skip to content
decodecodeveloper docs
Storefront → Blocks → Fresh reference archive

Fresh archive: Accept a section

Accepting Other Sections as Parameters in Your Section

Retired product documentation — Fresh and the former admin are retired. These instructions are preserved for migration and historical reference. New projects use Blocks 7.x and Studio's Site Editor.

Retired Fresh / Deno reference. This original guide preserves the earlier runtime APIs, Preact/HTMX examples, and any former admin steps. Use it when maintaining that runtime; consult the Studio Site Editor guides for current editing. Migration notes distinguish editor and framework migration.

Accepting Other Sections as Parameters in Your Section

In deco, you can create powerful and flexible Sections by accepting other sections as parameters. This allows you to build modular and composable components that can be easily customized and reused in different contexts.

Overview

When creating a Section that accepts other sections as parameters, you define an interface for the props of your Section component. This interface includes a property which is of type Section. The Section type is a generic type that represents any other section in deco.

Implementation

To create a Section that accepts other Sections as parameters, follow these steps:

  1. Import the Section type from deco/blocks/section.ts.

  2. Define an interface for the props of your section component. Include a property called myProp, which is of type Section.

// MySection.tsx
 
import { Section } from "deco/blocks/section.ts";
 
export interface Props {
  myProp: Section;
}
 
export default function MySection({ myProp: { Component, props } }: Props) {
  return (
    <div>
      <Component {...props} />
    </div>
  );
}
  1. Inside your section component, access the Component and props properties from the myProp prop. The Component property represents the component function of the section passed as a parameter, and the props property contains the props of that section.

Example

Let's say you have a section called ProductCardSection that renders a product card based on certain props:

// ProductCardSection.tsx
 
export interface Props {
  title: string;
  price: number;
  imageUrl: string;
}
 
export default function ProductCardSection({ title, price, imageUrl }: Props) {
  return (
    <div>
      ![]()
      <h3>{title}</h3>
      <p>{price}</p>
    </div>
  );
}

Now, you want to create a higher-order section called ProductContainerSection, which accepts a ProductCardSection as a parameter and wraps it in a container:

// ProductContainerSection.tsx
 
import { Section } from "deco/blocks/section.ts";
 
export interface Props {
  myProp: Section;
}
 
export default function ProductContainerSection(
  { myProp: { Component, props } }: Props,
) {
  return (
    <div className="flex gap-4">
      <Component {...props} />
    </div>
  );
}

With this setup, you can now use ProductContainerSection to wrap any other section, including the ProductCardSection, and add a container around it.

Now, let's say you want restrict your section to ProductCard because you have a lot of sections in your site but only that one should fit in that place, you can do the following:

// ProductCardSection.tsx
 
import { JSX } from "preact";
 
// Define a named type, for example, "ProductCard," pointing to `JSX.Element`
export type ProductCard = JSX.Element;
 
// Define the props interface
export interface Props {
  title: string;
  price: number;
  imageUrl: string;
}
 
// Implement the section and specify the return type as "ProductCard"
export default function ProductCardSection(
  { title, price, imageUrl }: Props,
): ProductCard {
  return (
    <div>
      ![]()
      <h3>{title}</h3>
      <p>{price}</p>
    </div>
  );
}

Now, you can depend directly on ProductCard:

// ProductContainerSection.tsx
 
import { Section } from "deco/blocks/section.ts";
import { ProductCard } from "./ProductCardSection.tsx";
 
// Specify the prop interface with `Section<ProductCard>`
export interface Props {
  myProp: Section<ProductCard>;
}
 
// Implement the section
export default function ProductContainerSection(
  { myProp: { Component, props } }: Props,
) {
  return (
    <div className="flex gap-4">
      <Component {...props} />
    </div>
  );
}

This ensures consistency and reinforces the concept of a named type, making it easier for developers to and business users constrain their sections as they wish!

Note

With the ability to accept other sections as parameters, you can create highly modular and customizable sections that adapt to different use cases and make your Live.ts applications even more powerful and flexible. Happy coding! 🧩🚀