DocsExtending PuckInternal Puck API

Internal Puck API

Puck exposes it’s internal API as PuckApi for extending Puck with custom functionality within custom fields, compositional interfaces or UI overrides.

Accessing the internal API

You can access PuckApi via two hooks:

  • usePuck - access PuckApi as part of your component render lifecycle
  • useGetPuck - access PuckApi outside of your component render lifecycle

Within the render lifecycle

To access the API within your render lifecycle, use the usePuck hook. We can use a selector to limit re-rendering to a specific part of the API.

import { createUsePuck } from "@measured/puck";
 
const usePuck = createUsePuck();
 
const Example = () => {
  // Use a selector so we only re-render when the selected type changes
  const type = usePuck((s) => s.selectedItem?.type || "Nothing");
 
  return <h2>{type} selected</h2>;
};

See the usePuck docs for a full API reference.

Outside of the render lifecycle

Often it’s not necessary to re-render your component when the PuckApi changes. Puck provides the useGetPuck hook for use-cases where you need the latest data outside of a render.

import { useGetPuck } from "@measured/puck";
 
const Example = () => {
  const getPuck = useGetPuck();
 
  const handleClick = useCallback(() => {
    // Get the latest PuckApi value
    const { appState } = getPuck();
 
    console.log(appState);
  }, [getPuck]);
 
  return <button onClick={handleClick}>Click me</button>;
};

See the useGetPuck docs for a full API reference.

Usage in practice

Generally, you’ll want to combine this with composition, UI overrides or custom fields. PuckApi cannot currently be accessed outside of these contexts.

Here’s an example using the internal API to render the page data as JSON using composition:

import { Puck, createUsePuck } from "@measured/puck";
 
const usePuck = createUsePuck();
 
const JSONRenderer = () => {
  const appState = usePuck((s) => s.appState);
 
  return <div>{JSON.stringify(appState.data)}</div>;
};
 
export function Editor() {
  return (
    <Puck>
      <JSONRenderer />
    </Puck>
  );
}

Further reading