Skip to content

Inline UI Components

Use Configure hosted UI surfaces for user consent, profile seeding, connector setup, and action approval. Use the SDK profile runtime for profile reads, model tools, tool execution, and memory writes.

For chat products with sign-in, pair these components with Continue with Configure: SSO authenticates the user, then inline Configure lets them manage profile permissions and connect tools without leaving the chat. Link-only is the fallback when the host product has no sign-in or OAuth provider row.

Existing Agent Integration

For chat products, place Configure in the same + menu that holds images and files. If the user already completed Continue with Configure, this row should behave as "Manage Configure" and open permissions/connectors/personalization. If the user has not authenticated with Configure yet, it falls back to Configure Link and returns an agent-scoped token after consent.

html
<script src="https://configure.dev/js/configure.js"></script>
<div id="personalization-entry"></div>

<script>
  Configure.personalizationButton({
    el: "#personalization-entry",
    publishableKey: "pk_...",
    agent: "your-agent",
    agentName: "Your Agent",
    personalizationLabel: "Manage Configure",
    placeholder: "Ask your agent anything",
    font: "Inter, -apple-system, BlinkMacSystemFont, sans-serif",
    onImage: () => openImagePicker(),
    onFile: () => openFilePicker(),
    onEvent(event) {
      if (event.type === "configure:linked") {
        fetch("/api/configure/session", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ token: event.payload.token }),
        });
      }
    },
  });
</script>

For SSO-authenticated users, keep OAuth access and refresh tokens on the backend. Hosted Configure UI can reuse the Configure-origin session created during SSO. Pass a browser-safe Configure handoff token or userId only when your backend intentionally returns one for hosted UI; never pass OAuth access or refresh tokens to browser JavaScript.

The Images and Files rows are host-owned. The helper emits configure:image-select and configure:file-select, and also accepts onImage and onFile callbacks.

The Personalization row emits configure:personalization-open when it needs to open Link, and configure:personalization-toggle when an already-linked user turns personalization on or off locally. Use showImages: false, showFiles: false, data-hide-images, or data-hide-files if the host owns a narrower menu.

If the host already has an inline integrations list instead of a + menu, use the Configure lockup variant. It renders a rounded rectangle integration button with the white Configure lockup on Configure grey. Pressing it opens inline Configure in the chat flow.

js
Configure.personalizationButton({
  el: "#configure-integration",
  publishableKey: "pk_...",
  agent: "your-agent",
  agentName: "Your Agent",
  personalizationLabel: "Manage Configure",
  variant: "integration",
  onEvent(event) {
    if (event.type === "configure:linked") {
      fetch("/api/configure/session", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ token: event.payload.token }),
      });
    }
  },
});

Declarative equivalent:

html
<div
  data-configure-personalization
  data-publishable-key="pk_..."
  data-agent="your-agent"
  data-agent-name="Your Agent"
  data-placeholder="Ask your agent anything"
  data-image-label="Images"
  data-file-label="Files"
  data-font="Inter, -apple-system, BlinkMacSystemFont, sans-serif">
</div>

Integration-list equivalent:

html
<div
  data-configure-personalization
  data-variant="integration"
  data-publishable-key="pk_..."
  data-agent="your-agent"
  data-agent-name="Your Agent">
</div>

Settings Page Or Static Button

This path is not for chat products. Use it only when there is no chat composer to attach to — a settings page, an integrations screen, or a standalone button. Use the declarative data-configure-link trigger and read the token from event.detail.token:

html
<script src="https://configure.dev/js/configure.js"></script>
<button
  data-configure-link
  data-publishable-key="pk_..."
  data-agent="your-agent">
  Personalize
</button>

<script>
  document.addEventListener("configure:linked", (event) => {
    fetch("/api/configure/session", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ token: event.detail.token }),
    });
  });
</script>

Token event shapes differ by entry point: Configure.personalizationButton({ onEvent }) exposes the token at event.payload.token; the declarative configure:linked DOM event exposes it at event.detail.token. Send only the token to the backend; never put it in the model prompt.

Backend Step

After Continue with Configure, use the server-side OAuth access token. After Link fallback, send only the configure:linked token to your backend. In both cases, create the profile runtime on the server:

ts
const profile = configure.profile({ token });
const read = await profile.read();
const context = read.profile.format({ guidelines: true });

The model receives formatted profile context and model-callable tools, not browser credentials, raw tokens, or user IDs.

Connector Setup

Show connector state with the hosted connections surface:

js
Configure.connections({
  el: "#configure-connections",
  publishableKey: "pk_...",
  agent: "your-agent",
  connectors: ["gmail", "calendar", "drive", "notion", "sheets"],
  token,
});

After a user connects Gmail, Calendar, Drive, Notion, or Google Sheets, your server may opt into matching connector tools:

ts
profile.tools({ connectors: ["gmail"] });

Actions

Use the hosted tool approval surface to collect explicit approval before running action tools:

ts
profile.tools({ actions: ["email.send"] });

The component captures consent. The server still executes the model tool call with profile.executeTool().

Personalization infrastructure for agents