UI overrides
The overrides API is highly experimental and is likely to experience breaking changes.
Overrides allow you to change how Puck renders its default interface. It can be used with or without composition.
There are many different overrides available. See the overrides
API reference for the full list.
Implementing an override
Use the overrides
prop to implement an override:
import { Puck } from "@measured/puck";
export function Editor() {
return (
<Puck
// ...
overrides={{
// Render a custom element for each item in the component list
componentItem: ({ name }) => (
<div style={{ backgroundColor: "hotpink" }}>{name}</div>
),
}}
/>
);
}
Examples
Custom publish button
A common use case is to override the Puck header. You can either use the header
override to change the entire header, or use the headerActions
override to inject new controls into the header and change the publish button.
Here’s an example that also leverage the internal Puck API to replace the default publish button with a custom one:
import { Puck, createUsePuck } from "@measured/puck";
const usePuck = createUsePuck();
const save = () => {};
export function Editor() {
return (
<Puck
// ...
overrides={{
headerActions: ({ children }) => {
const appState = usePuck((s) => s.appState);
return (
<>
<button
onClick={() => {
save(appState.data);
}}
>
Save
</button>
{/* Render default header actions, such as the default Button */}
{/*{children}*/}
</>
);
},
}}
/>
);
}
Custom field type
An advanced use case is overriding all fields of a certain type by specifying the fieldTypes
override.
import { Puck } from "@measured/puck";
export function Editor() {
return (
<Puck
// ...
overrides={{
fieldTypes: {
// Override all text fields with a custom input
text: ({ name, onChange, value }) => (
<input
defaultValue={value}
name={name}
onChange={(e) => onChange(e.currentTarget.value)}
style={{ border: "1px solid black", padding: 4 }}
/>
),
},
}}
/>
);
}