Data Migration
Version migrating
Puck follows semantic versioning. Major releases may introduce breaking changes for your Data payload.
Puck provides the migrate
helper method to help migrate legacy data payloads to the latest data model, transforming any deprecated properties to their latest counterparts as described by the Data API reference.
import { migrate } from "@measured/puck";
migrate(legacyData);
Breaking changes to props
Renaming or removing the props passed to your components are considered breaking changes. Any existing Data payloads that reference these props will be unable to render.
There are two strategies for dealing with this:
- Retaining backwards-compatible props
- Implementing a prop migration
Retaining backwards-compatibility
The easiest way to avoid breaking changes is to implement your prop changes in a backwards compatible manor:
const config = {
HeadingBlock: ({ title, heading }) => <h1>{heading || title}</h1>,
};
Implementing a prop migration
It will often be preferrable to update the underlying Data payload. Puck provides the transformProps
utility method to conveniently transform the props for a given component throughout the payload.
import { transformProps } from "@measured/puck";
const config = {
// Renamed `title` prop to `heading`
HeadingBlock: ({ heading }) => <h1>{heading}</h1>,
};
const data = {
content: [
// HeadingBlock references the legacy `title` prop
{ type: "HeadingBlock", props: { title: "Hello, world" } },
],
};
const updatedData = transformProps(data, {
// Map `heading` to the legacy `title` prop
HeadingBlock: ({ title, ...props }) => ({ heading: title, ...props }),
});
console.log(updatedData);
// { content: [{ type: "HeadingBlock", props: { heading: "Hello, world" } }] };
You may choose to run this transform every time you render your content, or perform a batch operation against your database.
import { Puck, Render, transformProps } from "@measured/puck";
const transforms = {
HeadingBlock: ({ title, ...props }) => ({ heading: title, ...props }),
};
export const MyEditor = ({ data, config }) => (
<Puck data={transformProps(data, transforms)} config={config} />
);
export const MyPage = ({ data, config }) => (
<Render data={transformProps(data, transforms)} config={config} />
);