{"site":{"name":"Koji","description":"AI-native customer research platform that helps teams conduct, analyze, and synthesize customer interviews at scale.","url":"https://www.koji.so","contentTypes":["blog","documentation"],"lastUpdated":"2026-05-18T13:31:48.866Z"},"content":[{"type":"documentation","id":"0a11c680-bf35-4e7b-9fba-ba879e13d02e","slug":"using-the-embed-widget","title":"Using the Embed Widget","url":"https://www.koji.so/docs/using-the-embed-widget","summary":"The Koji embed widget is an iframe you can place on any webpage. It supports dark and light themes, external_id tracking, event listeners for interview lifecycle events, structured question widgets, and a React wrapper. Voice mode works when the microphone permission attribute is included.","content":"The Koji embed widget lets you place an interview directly on your website so participants never have to leave the page. It works as a standard iframe and takes just a couple of minutes to set up.\n\n## When to Use the Embed Widget\n\nEmbedding is a great fit when you want to:\n\n- Collect feedback on a product page, pricing page, or help center article\n- Run a post-purchase interview on a thank-you or confirmation page\n- Integrate an interview into an existing web application or dashboard\n- Keep participants in your own branded environment\n\nIf you prefer to send participants to a dedicated interview page instead, see [Sharing Your Interview Link](/docs/sharing-your-interview-link).\n\n## Getting the Embed Code\n\n1. Open your project and navigate to the **Integrate** tab.\n2. You will see the **Embed Code Generator**, which provides ready-to-copy code snippets.\n3. Choose your configuration options (theme, dimensions) and copy the code.\n\nThe generator provides three code formats:\n\n- **Basic iframe** — the simplest option, just paste and go\n- **iframe with events** — includes a JavaScript listener for interview lifecycle events\n- **React component** — a ready-made React wrapper for Next.js, Create React App, or similar frameworks\n\n## Basic Iframe\n\nThe simplest embed is a standard HTML iframe:\n\n```html\n<iframe\n  src=\"https://yourdomain.com/embed/YOUR_PROJECT_ID\"\n  width=\"100%\"\n  height=\"700px\"\n  frameborder=\"0\"\n  allow=\"microphone\"\n  style=\"border: none; border-radius: 12px;\"\n></iframe>\n```\n\nPaste this into any HTML page, CMS block, or template. The interview will render inside the frame and handle the full participant flow — landing page, mode selection, intake form, conversation, and completion.\n\n### Key Attributes\n\n- **`allow=\"microphone\"`** — required if you want participants to use voice mode. Without this attribute, the browser will block microphone access inside the iframe.\n- **`width` and `height`** — adjust to fit your page layout. A height of 700 pixels works well for most setups.\n- **`style`** — the default border-radius of 12px gives the embed rounded corners to blend in with modern designs. Adjust this value to match your site's design language.\n\n## Configuration Options\n\n### Theme\n\nBy default, the embed uses the dark theme. You can switch to light mode by adding a query parameter:\n\n```\nhttps://yourdomain.com/embed/YOUR_PROJECT_ID?theme=light\n```\n\nChoose the theme that matches your website's design.\n\n### API Key\n\nIf you want to track embed usage or enforce origin restrictions, you can pass an API key:\n\n```\nhttps://yourdomain.com/embed/YOUR_PROJECT_ID?api_key=YOUR_KEY\n```\n\nThis is optional for basic embeds but recommended if you are embedding on a production site.\n\n### External ID\n\nTo associate embedded interviews with users in your own system, pass an external identifier:\n\n```\nhttps://yourdomain.com/embed/YOUR_PROJECT_ID?external_id=user_abc123\n```\n\nThe `external_id` is attached to the respondent record and can be used to match interview data back to your internal user database. You can combine multiple parameters:\n\n```\nhttps://yourdomain.com/embed/YOUR_PROJECT_ID?theme=light&api_key=YOUR_KEY&external_id=user_abc123\n```\n\n## Structured Questions in Embeds\n\nIf your study includes [structured questions](/docs/structured-questions-guide) such as scales, multiple choice, ranking, or yes/no questions, the interactive question widgets render fully within the embed. Participants can interact with sliders, select options, and drag to rank items just as they would on the standalone interview page.\n\n## Listening for Events\n\nThe embed communicates with your parent page through the browser's `postMessage` API. This lets you react to interview milestones — for example, showing a custom thank-you message or redirecting the user after completion.\n\nAdd a message listener to your page:\n\n```javascript\nwindow.addEventListener('message', function(event) {\n  // Always verify the origin for security\n  if (event.origin !== 'https://yourdomain.com') return;\n\n  switch(event.data.type) {\n    case 'koji:ready':\n      // The interview has loaded and is ready\n      break;\n    case 'koji:interview_started':\n      // The participant has begun the conversation\n      break;\n    case 'koji:interview_completed':\n      // The interview is finished — event.data.result has details\n      break;\n  }\n});\n```\n\n### Available Events\n\n| Event | When It Fires |\n|---|---|\n| `koji:ready` | The embed has loaded and the landing page is visible |\n| `koji:interview_started` | The participant has started the conversation |\n| `koji:interview_completed` | The interview has ended (includes result data) |\n\nUse the `koji:interview_completed` event to trigger your own follow-up actions, such as showing a discount code, redirecting to another page, or logging the completion in your analytics.\n\n## React Integration\n\nIf your site uses React, the embed code generator provides a ready-made component:\n\n```jsx\nfunction KojiInterview({ onComplete }) {\n  const iframeRef = useRef(null);\n\n  useEffect(() => {\n    function handleMessage(event) {\n      if (event.origin !== 'https://yourdomain.com') return;\n      if (event.data.type === 'koji:interview_completed') {\n        onComplete?.(event.data.result);\n      }\n    }\n    window.addEventListener('message', handleMessage);\n    return () => window.removeEventListener('message', handleMessage);\n  }, [onComplete]);\n\n  return (\n    <iframe\n      ref={iframeRef}\n      src=\"https://yourdomain.com/embed/YOUR_PROJECT_ID\"\n      width=\"100%\"\n      height=\"700px\"\n      frameBorder=\"0\"\n      allow=\"microphone\"\n      style={{ border: 'none', borderRadius: '12px' }}\n    />\n  );\n}\n```\n\nDrop this into your React app and pass an `onComplete` callback to handle interview completion.\n\n## Responsive Sizing\n\nFor responsive layouts, wrap the iframe in a container and use CSS to control its dimensions:\n\n```html\n<div style=\"width: 100%; max-width: 800px; margin: 0 auto;\">\n  <iframe\n    src=\"https://yourdomain.com/embed/YOUR_PROJECT_ID\"\n    width=\"100%\"\n    height=\"700px\"\n    frameborder=\"0\"\n    allow=\"microphone\"\n    style=\"border: none; border-radius: 12px;\"\n  ></iframe>\n</div>\n```\n\nOn mobile, the embed adjusts its internal layout automatically. A minimum width of 320 pixels is recommended.\n\n## Security Considerations\n\n- **Origin verification:** Always check `event.origin` in your message listener to prevent cross-origin attacks.\n- **API key restrictions:** If you use an API key, configure allowed origins in your project settings so only your domain can load the embed.\n- **HTTPS required:** The embed must be loaded over HTTPS to enable microphone access for voice interviews.\n\n## Troubleshooting\n\n- **Microphone not working in embed:** Make sure the `allow=\"microphone\"` attribute is present on the iframe tag. The parent page must also be served over HTTPS.\n- **Embed not loading:** Verify the project ID in the URL is correct and that the study is published.\n- **Events not firing:** Confirm you are checking the correct origin in your event listener.\n\n## Next Steps\n\n- [Sharing Your Interview Link](/docs/sharing-your-interview-link) — alternative distribution methods\n- [Headless API Overview](/docs/headless-api-overview) — start interviews programmatically from your backend\n- [Customizing Branding](/docs/customizing-branding) — make the embed match your site's look and feel\n- [Structured Questions Guide](/docs/structured-questions-guide) — add interactive question types to your study","category":"Collecting Responses","lastModified":"2026-05-14T03:18:53.717222+00:00","metaTitle":"Using the Embed Widget — Koji Docs","metaDescription":"Embed Koji interviews on your website with an iframe. Includes configuration options, event listeners, and React integration.","keywords":["embed widget","iframe","website integration","embed code","React component","postMessage"],"aiSummary":"The Koji embed widget is an iframe you can place on any webpage. It supports dark and light themes, external_id tracking, event listeners for interview lifecycle events, structured question widgets, and a React wrapper. Voice mode works when the microphone permission attribute is included.","aiPrerequisites":["sharing-your-interview-link"],"aiLearningOutcomes":["Add the embed widget to a webpage","Configure theme and dimensions","Listen for interview lifecycle events","Integrate with a React application"],"aiDifficulty":"intermediate","aiEstimatedTime":"7 min read"}],"pagination":{"total":1,"returned":1,"offset":0}}