feat: add embed app — standalone widget for external sites - #5
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Free Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (26)
📝 WalkthroughWalkthroughThis PR adds a new ChangesEmbed Widget Application
Estimated code review effort: 2 (Simple) | ~15 minutes Agent Skill Documentation
Estimated code review effort: 1 (Trivial) | ~10 minutes Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login. Comment |
There was a problem hiding this comment.
Pull request overview
This PR introduces a new apps/embed Vite-based project intended to ship a standalone, externally-embeddable widget bundle (IIFE) plus local demo/landing pages and supporting configuration.
Changes:
- Adds a Vite “library mode” build that outputs an embeddable widget bundle.
- Implements the widget loader (
embed.ts) that injects a floating button + iframe and exposes a global control API. - Adds local demo/landing HTML plus project scaffolding (TypeScript, ESLint) and agent skill documentation under
.agents/.
Reviewed changes
Copilot reviewed 25 out of 28 changed files in this pull request and generated 18 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/embed/vite.config.ts | Vite library build + dev server settings for the embed bundle. |
| apps/embed/vite-env.d.ts | Declares import.meta.env.VITE_WIDGET_URL typing for Vite. |
| apps/embed/tsconfig.json | TypeScript configuration for the embed app. |
| apps/embed/package.json | New package definition and build/dev scripts for embed app. |
| apps/embed/landing.html | Large static landing page intended for the embed app. |
| apps/embed/icons.ts | Inline SVG strings used for the floating button icons. |
| apps/embed/eslint.config.js | ESLint config wiring to shared workspace base config. |
| apps/embed/embed.ts | Main embed loader: injects button/iframe, message handling, global API exposure. |
| apps/embed/demo.html | Local demo page for testing the embed widget behavior/config. |
| apps/embed/config.ts | Embed runtime config (widget URL, defaults). |
| apps/embed/.agents/skills/shadcn/SKILL.md | Adds shadcn skill documentation content under embed app. |
| apps/embed/.agents/skills/shadcn/rules/styling.md | shadcn styling rules documentation. |
| apps/embed/.agents/skills/shadcn/rules/icons.md | shadcn icon usage rules documentation. |
| apps/embed/.agents/skills/shadcn/rules/forms.md | shadcn forms rules documentation. |
| apps/embed/.agents/skills/shadcn/rules/composition.md | shadcn component composition rules documentation. |
| apps/embed/.agents/skills/shadcn/rules/base-vs-radix.md | shadcn base vs radix rules documentation. |
| apps/embed/.agents/skills/shadcn/registry.md | shadcn registry authoring documentation. |
| apps/embed/.agents/skills/shadcn/mcp.md | shadcn MCP usage documentation. |
| apps/embed/.agents/skills/shadcn/evals/evals.json | shadcn eval definitions. |
| apps/embed/.agents/skills/shadcn/customization.md | shadcn customization/theming documentation. |
| apps/embed/.agents/skills/shadcn/cli.md | shadcn CLI reference documentation. |
| apps/embed/.agents/skills/shadcn/agents/openai.yml | shadcn agent metadata configuration. |
| apps/embed/.agents/skills/animation-vocabulary/SKILL.md | Animation vocabulary skill documentation. |
| apps/embed/.agents/skills/agent-browser/SKILL.md | Agent-browser skill stub documentation. |
| apps/embed/_extract_head.txt | Unreferenced extracted HTML head artifact. |
| apps/embed/_extract_body.txt | Unreferenced extracted HTML body artifact. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| function buildWidgetUrl(): string { | ||
| const params = new URLSearchParams(); | ||
| params.append('organizationId', organizationId!); | ||
| return `${EMBED_CONFIG.WIDGET_URL}?${params.toString()}`; | ||
| } |
| function handleMessage(event: MessageEvent) { | ||
| if (event.origin !== new URL(EMBED_CONFIG.WIDGET_URL).origin) return; | ||
|
|
||
| const { type, payload } = event.data; | ||
|
|
||
| switch (type) { | ||
| case 'close': | ||
| hide(); | ||
| break; | ||
| case 'resize': | ||
| if (payload.height && container) { | ||
| container.style.height = `${payload.height}px`; | ||
| } | ||
| break; | ||
| } | ||
| } |
| button = document.createElement('button'); | ||
| button.id = 'echo-widget-button'; | ||
| button.innerHTML = chatBubbleIcon; |
| // Change button icon to close | ||
| button.innerHTML = closeIcon; | ||
| } |
| // Change button icon back to chat | ||
| button.innerHTML = chatBubbleIcon; | ||
| button.style.background = '#3b82f6'; | ||
| } |
| <script src="https://unpkg.com/lucide@latest"></script> | ||
| <script src="https://cdn.tailwindcss.com"></script> |
| <!DOCTYPE html> | ||
| <html lang="en" class="dark"> | ||
| <head> |
| function destroy() { | ||
| window.removeEventListener('message', handleMessage); | ||
| if (container) { |
| <!-- Announcement Bar --> | ||
| <div class="bg-gradient-to-r from-brand-dark to-purple-600 text-white text-sm py-2.5 text-center relative overflow-hidden"> | ||
| <div class="relative z-10 flex items-center justify-center gap-2"> |
| // Create iframe | ||
| iframe = document.createElement('iframe'); | ||
| iframe.src = buildWidgetUrl(); | ||
| iframe.style.cssText = ` | ||
| width: 100%; | ||
| height: 100%; | ||
| border: none; | ||
| `; | ||
| // Add permissions for microphone and clipboard | ||
| iframe.allow = 'microphone; clipboard-read; clipboard-write'; | ||
|
|
Summary by CodeRabbit
New Features
Documentation