usePuck

A hook for building custom components that can interact with Puck. The best way to access usePuck is via the createUsePuck() factory.

import { createUsePuck } from "@measured/puck";
 
const usePuck = createUsePuck();
 
const Example = () => {
  const type = usePuck((s) => s.selectedItem?.type || "Nothing");
 
  return <h2>{type} selected</h2>;
};

You can also access usePuck as a direct export, but you won’t be able to use selectors, resulting in unwanted re-renders and degraded performance.

Components using the usePuck hook must be rendered within the <Puck> context as children, overrides or plugins.

Args

ParamExampleType
selector(data)(s: UsePuckData) => s.appStateFunction

selector(data)

A selector function that describes what usePuck returns. Receives UsePuckData and returns anything. Be as granular as possible to minimize re-renders.

// Good: only re-render when the `selectedItem` changes
const selectedItem = usePuck((s) => s.selectedItem);
 
// Bad: re-render when anything changes
const { selectedItem } = usePuck();
const { selectedItem } = usePuck((s) => s);
 
// Bad: selector creates a new object reference, causing an infinite comparison loop
const { selectedItem } = usePuck((s) => ({ ...s.selectedItem }));

Returns

Whatever is returned by the selector.

UsePuckData

ParamExampleType
appState{ data: {}, ui: {} }AppState
dispatch(action: PuckAction) => voidFunction
getPermissions() => ({ delete: true })Function
history{}Object
refreshPermissions() => voidFunction
selectedItem{ type: "Heading", props: {id: "my-heading"} }ComponentData

appState

The current application state for this Puck instance.

console.log(appState.data);
// { content: [], root: {}, zones: {} }

dispatch(action)

Execute an action to mutate the Puck application state.

dispatch({
  type: "setUi",
  ui: {
    leftSideBarVisible: false,
  },
});

getPermissions(params)

Get global, component or resolved dynamic permissions.

getPermissions();
// { delete: true, edit: true }

Params

ParamExampleType
item{ type: "HeadingBlock", props: { id: "1234" } }Object
rootfalseBoolean
type"HeadingBlock"String
item

Specify item to retrieve the permissions for a given component instance, resolving any dynamic permissions for that component, as set by the resolvePermissions parameter.

getPermissions({
  item: { type: "HeadingBlock", props: { id: "Heading-1234" } }, // Get resolved permissions for Heading-1234
});
// { delete: false }

The getPermissions function will be redefined when after resolving dynamic permissions, so it’s generally required to wrap it in a useEffect hook:

const [myPermissions, setMyPermissions] = useState(getPermissions());
 
useEffect(() => {
  setMyPermissions(getPermissions());
}, [getPermissions]);
root

Specify root to retrieve the permissions for the root, as set by the permissions parameter.

getPermissions({ root: true });
// { delete: false }
type

Specify type to retrieve the permissions for a given component type, as set by the permissions parameter.

getPermissions({ type: "HeadingBlock" });
// { delete: false }

history

The history API provides programmatic access to the undo/redo AppState history.

ParamExampleType
back() => voidFunction
forward() => voidFunction
hasPasttrueBoolean
hasFuturefalseBoolean
histories[{ id: 'abc123', data: {} }]History[]
index5Number
setHistoriessetHistories: (histories) => voidFunction
setHistoryIndexsetHistoryIndex: (index) => voidFunction

history.back()

A function to move the app state back through the histories.

history.forward()

A function to move the app state forward through the histories.

history.hasPast

A boolean describing whether or not the present app state has past history items.

history.hasFuture

A boolean describing whether or not the present app state has future history items.

history.histories

An array describing the recorded history as History objects.

History params
ParamExampleType
state{}AppState
idabc123String
state

The app state payload for this history entry.

id

An optional ID for this history entry.

history.index

The index of the currently selected history in history.histories

setHistories

A function to set the history state.

setHistories([]); // clears all history

setHistoryIndex

A function to set current history index.

setHistoryIndex(2);

refreshPermissions(params)

Force the permissions to refresh, running all resolvePermissions functions and skipping the cache.

resolvePermissions(); // Refresh all permissions

Params

ParamExampleType
item{ type: "HeadingBlock", props: { id: "1234" } }Object
rootfalseBoolean
type"HeadingBlock"String
item

Specify item to refresh the permissions for a given component instance only.

refreshPermissions({
  item: { type: "HeadingBlock", props: { id: "Heading-1234" } }, // Force refresh the resolved permissions for Heading-1234
});
root

Specify root to refresh the permissions for the root only.

refreshPermissions({ root: true });
type

Specify type to refresh the permissions for all components of a given component type.

refreshPermissions({ type: "HeadingBlock" });

selectedItem

The currently selected item, as defined by appState.ui.itemSelector.

console.log(selectedItem);
// { type: "Heading", props: {id: "my-heading"} }