DocsGuidesMigrationsDropZones to Slots

How to migrate from DropZones to Slots

This guide will help you migrate from DropZones to Slots.


Slot fields replace the <DropZone> component, introducing an inline data model that supports defaultProps, resolveData and Server Components out-of-the-box.

Replace DropZone instances

Replace your <DropZone> instances with slot fields and the slot render function.

Before

const config = {
  components: {
    Example: {
      render: () => {
        return <DropZone zone="items" allow={["HeadingBlock"]} />;
      },
    },
  },
};

After

const config = {
  components: {
    Example: {
      fields: {
        items: {
          type: "slot",
        },
      },
      defaultProps: {
        items: [], // Slots support defaultProps and other APIs like resolveData
      },
      render: ({ items: Items }) => {
        return <Items allow={["HeadingBlock"]} />; // Slots support most DropZone APIs
      },
    },
  },
};

The data model

The slot data model is inline and recursive. This means that instead of storing data in a global zones object, data is stored as arrays of ComponentData as a prop.

Before

{
  "content": [
    {
      "type": "Grid",
      "props": {
        "id": "Grid-12345"
      }
    }
  ],
  "zones": {
    "Grid-12345:items": [
      {
        "type": "HeadingBlock",
        "props": {
          "id": "Heading-12345",
          "title": "Hello, world"
        }
      }
    ]
  }
}

After

{
  "content": [
    {
      "type": "Grid",
      "props": {
        "id": "Grid-12345",
        "items": [
          {
            "type": "HeadingBlock",
            "props": {
              "id": "Heading-12345",
              "title": "Hello, world"
            }
          }
        ]
      }
    }
  ]
}

Migrating legacy data

For new slots, you don’t need to do anything. If you’re migrating existing DropZones to slots, you will need to migrate your the data accordingly. Puck provides the migrate() helper to help with this:

import { migrate } from "@measured/puck";
import config from "puck.config.tsx";
 
const newData = migrate(legacyData, config);

This will migrate any existing zone in zones where you have defined a slot with the same name.

Further reading