Skip to content

Components ​

The Quickstart uses your own connection button and redirects the user to the hosted flow. Use Configure components to embed that flow in your app.

https://configure.dev/js/configure.js provides the Configure.* functions. https://configure.dev/components/configure-components.global.js defines the web components. Include each required script once per page.

publishableKey is your pk_ key, safe in the browser, and agent is your agent handle. Both come from npx configure setup --users. displayName is what the user reads; agent is the identity every approval and token is bound to.

Composer button ​

Use the composer button in a chat interface. Its + menu includes a Personalization option that opens the hosted flow inline. Set linkEl to mount the flow in a dismissible panel in the assistant message area.

html
<script src="https://configure.dev/js/configure.js"></script>

<div id="configure-entry"></div>
<div id="configure-link-host"></div>

<script>
  Configure.personalizationButton({
    el: "#configure-entry",
    linkEl: "#configure-link-host",
    publishableKey: "pk_...",
    agent: "your-agent",
    displayName: "Your App",
    theme: "light",                 // or "dark"; omit it and the script warns and follows the system
    onImage: () => openImagePicker(),
    onFile: () => openFilePicker(),
  });
</script>

Allow the flow container to use the full width of the assistant message area. A 420px maximum width is too narrow for the hosted flow.

Your own button ​

Use your app's existing button style for a custom connection button. Link it to the server route that starts the hosted flow. Configure redirects the user to your callback afterward. Follow Quickstart steps 2 through 5.

Smry's home page with the connection button circled in red: it reads Connect, followed by the Claude, ChatGPT, Gemini, and Grok marks

A connection button under the composer on Smry's home page.
html
<a class="chip" href="/configure/start">Connect</a>

The route creates a connection URL with returnUrl and redirects the user to it. profileFor is the handle from the Quickstart, and RETURN_URL is your callback route's https address, a constant:

ts
const RETURN_URL = "https://yourapp.com/configure/return";

app.get("/configure/start", async (req, res) => {
  const connect = await profileFor(req.user.id).connect({ returnUrl: RETURN_URL });
  res.redirect(connect.connect_url);   // Configure's page, then back to RETURN_URL
});

Configure redirects the user to your callback route: Quickstart, step 5.

Integration button ​

Use the integration button in settings or an integrations list. The component renders a Connect or Manage control that opens the hosted flow.

html
<script src="https://configure.dev/js/configure.js"></script>
<script src="https://configure.dev/components/configure-components.global.js"></script>

<configure-personalization-button
  variant="integration"
  external-id="user_123"
></configure-personalization-button>

variant is menu, the composer button above as a raw element, or integration. With manual the element announces its events and never opens the flow, which is how the demos on this page run.

Use Configure.link() to mount the hosted flow in a container you select. Handle its completion event to receive the token. It uses the same authorization flow as the composer and integration buttons.

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

<script>
  Configure.link({
    el: "#configure-link",
    publishableKey: "pk_...",
    agent: "your-agent",
    displayName: "Your App",
    theme: "light",
    onEvent: (event) => {
      if (event.type === "configure:linked") {
        // event.payload = { token, userId, tokenUse }
        sendTokenToYourBackend(event.payload.token);
      }
    },
  });
</script>

Configure.link() returns a frame handle, not the token. The token arrives in configure:linked, through onEvent or as a DOM CustomEvent on the mount element. Send it to your server and use it there with configure.profile({ token }).

Connected ​

The composer button updates its state when the hosted flow completes on the page. After reloads, or for a custom button, use the profile context cached by your server to determine the connection state.

ts
// The refresh in Quickstart step 6 stores { text, refreshedAt }. text is null until the user connects.
const stored = await store.get(user.id);
const label = stored?.text ? "Connected" : "Connect";

Render the state from the cached Configure response and refresh it daily. This avoids a profile request on each page load. Do not infer connection status from browser events alone.

Approval card ​

Use the approval card to confirm email sends and calendar event creation. It displays the tool and its parameters. If the user does not respond before the timeout, it denies the action. The card emits an event with the decision.

html
<configure-tool-approval
  action-id="call_123"
  tool="configure_email_send"
  timeout-seconds="60"
></configure-tool-approval>
<script>
  const card = document.querySelector("configure-tool-approval");
  card.params = { to: "sam@example.com", subject: "Intro" };        // a property, not an attribute
  card.addEventListener("configure:tool-approve", (e) => runTool(e.detail.actionId));
  card.addEventListener("configure:tool-deny", (e) => skipTool(e.detail.actionId));
</script>

configure:tool-always-allow fires when the user approves future calls to that tool. Your app must store and apply that preference.

Attributes ​

On the raw <configure-personalization-button>:

AttributeDefaultWhat it does
variantmenumenu or integration
external-idYour user ID, used to associate the connection with the profile your server reads
connectorsWhich apps the flow offers, comma separated
personalization-labelThe text of the Personalization row
placeholderPlaceholder text in the composer slot
manualfalseAnnounce events only; never open the flow
hide-images, hide-filesfalseRemove the image or file rows from the + menu
image-label, file-labelText of the image and file rows
max-visibleHow many recent items the menu lists
show-actions, show-settingsShow the actions row and the settings row

Events the element announces: configure:personalization-open and configure:personalization-toggle as the flow opens and closes, configure:personalization-menu-toggle for the + menu, configure:linked when the link completes, configure:image-select and configure:file-select for the attachment rows, and configure:settings-press.

The buttons support keyboard navigation and visible focus states. They fit a 375px-wide viewport.

Infrastructure to connect agents, apps, and chats