Generate experiences with Puck AI
Read docs
Puck AIDesign Mode

Design Mode

In design mode, Puck AI creates new component types on the fly, incorporating components from your config where possible.

Setup

Configuration

Design mode is opt-in. To enable it, allow it on your server with ai.designMode.allowed:

import { puckHandler } from "@puckeditor/cloud-client";
 
export async function POST(request) {
  return puckHandler(request, {
    ai: {
      designMode: {
        allowed: true,
      },
    },
  });
}

Designed components persist in page data. To render them, pass your config through withDynamicConfig when rendering <Puck> or <Render>:

import { withDynamicConfig } from "@puckeditor/plugin-ai";
 
export function Editor({ data }) {
  const dynamicConfig = withDynamicConfig(config, data);
 
  return <Puck plugins={[aiPlugin]} config={dynamicConfig} data={data} />;
  // return <Render config={dynamicConfig} data={data} />;
}

Enable design mode

To enable design mode, you can either enable the design mode toggle in the client with designMode.visible, optionally making it the defaultMode:

const aiPlugin = createAiPlugin({
  designMode: {
    visible: true,
  },
  // defaultMode: "design",
});

or force it for every request via the server with ai.mode:

import { puckHandler } from "@puckeditor/cloud-client";
 
export async function POST(request) {
  return puckHandler(request, {
    ai: {
      mode: "design",
      designMode: {
        allowed: true,
      },
    },
  });
}

Customizing design behavior

You can configure design behavior using ai.designMode.

Custom instructions

Use instructions to give the agent instructions to follow when designing, such as brand colors or layout conventions:

return puckHandler(request, {
  ai: {
    designMode: {
      allowed: true,
      instructions:
        "Use our brand colors: #4285F4 for primary, #DB4437 for accents.",
    },
  },
});

Allowing scripts

Designed components and the page-wide global script can’t include client-side scripts by default. Set scripts to true to allow them:

return puckHandler(request, {
  ai: {
    designMode: {
      allowed: true,
      scripts: true,
    },
  },
});

Choosing a model

Design mode uses openai/gpt-5.6-luna by default. Set model to use a different one for design-mode requests:

return puckHandler(request, {
  ai: {
    designMode: {
      allowed: true,
      model: "openai/gpt-5.6-sol",
    },
  },
});

Set providerOptions to fine-tune the design model independently of ai.providerOptions:

return puckHandler(request, {
  ai: {
    designMode: {
      allowed: true,
      model: "openai/gpt-5.6-sol",
      providerOptions: {
        openai: { reasoningEffort: "high" },
      },
    },
  },
});

Headless generation

generate() accepts mode and designMode directly, without a server handler:

const page = await generate({
  prompt: "Create a pricing section with three tiers",
  config,
  mode: "design",
  designMode: { instructions: "Use our brand colors." },
});

See generate with design mode.

Global styles and scripts

Alongside the per-component CSS, the agent may create a page-wide stylesheet (for shared styles and CSS properties) and script tag (if enabled by your configuration).

Design mode data

Designed components and the page-wide globals are stored on the root of Puck’s Data. You can access them under the _dynamicConfig prop:

{
  "root": {
    "props": {
      "_dynamicConfig": {
        "components": {
          "MyComponent": {
            "html": "<div>Hello, world</div>",
            "fields": {}
          }
        },
        "styles": ":root { --brand: #4285f4; }",
        "script": "document.documentElement.dataset.ready = 'true';"
      }
    }
  }
}

Further reading