# Widget Platform — Full Documentation (widget.vn) > Embeddable widget platform for Vietnamese businesses. Multi-tenant, API-first architecture with Shadow DOM isolation. Built with Preact, Hono, tRPC, PostgreSQL + PostGIS. ## Overview Widget Platform provides 20 embeddable widgets designed for Vietnamese businesses. Each widget is a standalone JavaScript bundle (~3KB loader) that renders inside a Shadow DOM for CSS isolation. Widgets are configured via a REST API and managed through a multi-tenant admin dashboard. ## Architecture - **Runtime:** Bun - **API:** Hono + tRPC (port 3030) - **Embed:** Preact + Shadow DOM (~3KB loader) - **Database:** PostgreSQL 17 + PostGIS - **Cache/Queue:** Redis 7 + BullMQ - **Auth:** Better Auth - **ORM:** Prisma - **CDN:** Bun static server (staging), Cloudflare R2 + Workers (production) ## Widgets ### Vietnam Map (`MAP`) Interactive SVG map of Vietnam with 63 provinces/cities. Clickable regions, custom pins, color coding, tooltips. Supports both 63-province and 34-province layouts. Embed code: ```html
``` Dev preview: https://api.widget.vn/dev/map ### Store Locator (`STORE_LOCATOR`) Find nearby stores/branches on an interactive map. Search by province/district, filter by category, show directions. Powered by PostGIS geospatial queries. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/store-locator ### VietQR Payment (`VIETQR`) Generate VietQR payment QR codes for Vietnamese banks. Supports all major banks (Vietcombank, BIDV, Techcombank, etc.). Dynamic amount, memo, and recipient fields. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/vietqr ### Chat Bubble (`BUBBLE`) Floating chat bubble with multi-service support. Connect Messenger, Zalo, Telegram, WhatsApp, Viber, phone, and email in one widget. Customizable position and colors. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/bubble ### Countdown Timer (`COUNTDOWN`) Countdown timer for promotions, launches, and events. Displays days, hours, minutes, seconds. Configurable target date, timezone, and expired message. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/countdown ### Lunar Calendar (`LUNAR_CALENDAR`) Vietnamese lunar/solar calendar (Lich Am Duong). Shows lunar dates, Can Chi, good/bad hours, and Vietnamese holidays. Essential for Vietnamese businesses. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/lunar-calendar ### Cookie Consent (`COOKIE_CONSENT`) GDPR/PDPA-compliant cookie consent banner. Customizable categories (necessary, analytics, marketing), remember preferences, block scripts until consent. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/cookie-consent ### Scroll to Top (`SCROLL_TO_TOP`) Smooth scroll-to-top button that appears after scrolling. Customizable icon, position, offset threshold, and animation. Lightweight and accessible. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/scroll-to-top ### Top Bar Announcement (`TOP_BAR`) Sticky announcement bar at the top of the page. Support for promotions, news, alerts. Dismissible, with optional CTA button and countdown. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/top-bar ### Page View Counter (`PAGE_COUNTER`) Real-time page view counter. Tracks unique and total views with animated number display. Lightweight analytics widget for social proof. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/page-counter ### Job Board (`JOB_BOARD`) Embeddable job listings board. Post positions with descriptions, requirements, salary ranges. Application form with file upload. Filter by department and location. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/job-board ### Business Hours (`HOURS`) Display business opening hours in card, table, or compact layout. Shows open/closed status in real-time. Supports Vietnamese lunar holidays and special hours. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/business-hours ### Email Subscription (`EMAIL_SUBSCRIPTION`) Email subscription popup/inline form. Modal, slide-up, or inline variants. Collects subscriber emails with optional custom fields. Stores in Subscriber model. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/email-subscription ### Sticky Side Roll (`STICKY_SIDE_ROLL`) Sticky side banner that rolls out on hover/click. Perfect for promotions, contact info, or social links. Positioned on left or right edge of the viewport. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/sticky-side-roll ### Download App (`DOWNLOAD_APP`) App download banner with QR code, App Store, and Google Play badges. Promotes mobile app installation. Customizable app icon, name, and store URLs. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/download-app ### FAQ Accordion (`FAQ`) Frequently asked questions with accordion expand/collapse. Schema.org FAQPage markup for SEO. Customizable categories, search, and styling. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/faq ### Events / Mini-Games (`EVENTS`) Interactive events and mini-games widget. Spin wheel, scratch card, gift box, and quiz promotions. Configurable prizes, probabilities, and expiry dates. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/events ### Pricing Table (`PRICING_TABLE`) Responsive pricing table with multiple tiers. Monthly/yearly toggle, feature comparison, highlighted recommended plan. CTA buttons with custom URLs. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/pricing ### Testimonial Showcase (`TESTIMONIALS`) Customer testimonial carousel/grid. Display reviews with photos, ratings, company info. Multiple layouts: slider, grid, masonry. Social proof for conversions. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/testimonial ### Contact Form (`CONTACT_FORM`) Embeddable contact form with custom fields. Name, email, phone, message + configurable extra fields. Email notifications and submission storage. Embed code: ```html ``` Dev preview: https://api.widget.vn/dev/contact-form ## Public API Reference Base URL: `https://api.widget.vn/api/v1` All public endpoints require no authentication and support CORS (`*`). ### Widget Configuration ``` GET /widgets/:publicId/config ``` Returns the full widget configuration including type, settings, and theme. ### Store Locations ``` GET /widgets/:publicId/locations GET /widgets/:publicId/locations?province=01&district=001 ``` Returns locations for a Store Locator widget. Supports filtering by province/district code. ### Map Data ``` GET /widgets/:publicId/map-data ``` Returns map configuration, pins, and region data for Map widgets. ### Job Board ``` GET /widgets/:publicId/jobs GET /widgets/:publicId/jobs/:jobSlug POST /widgets/:publicId/jobs/:jobSlug/apply ``` List jobs, get job details, and submit applications with file uploads. ### Email Subscription ``` POST /widgets/:publicId/subscribe Content-Type: application/json { "email": "user@example.com", "name": "optional" } ``` ### Contact Form ``` POST /widgets/:publicId/contact Content-Type: application/json { "name": "...", "email": "...", "phone": "...", "message": "...", "fields": {} } ``` ### Widget Events & Stats ``` POST /widgets/:publicId/events GET /widgets/:publicId/stats ``` Track views, clicks, and other widget interactions. Get aggregated stats. ### Cookie Consent (NĐ 13/2023 Compliant) Record cookie consent for Vietnamese data protection compliance: ``` POST /widgets/:publicId/consent Content-Type: application/json { "action": "accept_all|reject_all|save_preferences", "categories": { "essential": true, "analytics": false, "marketing": false } } ``` The cookie consent widget automatically records consent server-side. Configure categories in the widget config: ```json { "categories": [ { "id": "essential", "label": "Thiết yếu", "required": true, "cookies": [ { "name": "session_id", "provider": "Your Site", "purpose": "Session", "retention": "Session" } ]}, { "id": "analytics", "label": "Phân tích", "required": false, "cookies": [ { "name": "_ga", "provider": "Google Analytics", "purpose": "User tracking", "retention": "2 years" } ]}, { "id": "marketing", "label": "Tiếp thị", "required": false, "cookies": [] } ], "showDetails": true, "showReopenButton": true, "recordConsent": true } ``` **Script blocking integration** — listen for consent events to conditionally load third-party scripts: ```javascript document.addEventListener('cookie-consent:updated', (e) => { const { consent } = e.detail; if (consent.analytics) { /* load GA, Hotjar, etc. */ } if (consent.marketing) { /* load FB Pixel, Google Ads, etc. */ } }); ``` Events emitted: `cookie-consent:accepted`, `cookie-consent:rejected`, `cookie-consent:updated` (each with `{ category, consent }` detail). ### Geo Data (Vietnam) ``` GET /geo/provinces GET /geo/provinces/:code GET /geo/districts/:code ``` Vietnamese administrative divisions: 63 provinces, 700+ districts, 10,000+ wards. Includes coordinates, population, and area data. ## Embedding ### Script Tag (recommended) ```html ``` ### CSS Custom Properties (Theming) All widgets support CSS custom properties for theming: ```css #my-widget { --wgt-primary: #2563eb; --wgt-bg: #ffffff; --wgt-text: #1f2937; --wgt-radius: 8px; --wgt-font: system-ui, sans-serif; } ``` ## Tenant Isolation All data is scoped by `tenantId`. Public API uses `widget.publicId` for access. Widgets are created and managed through the admin tRPC API (authenticated). ## Legal Notes - No UGC/comments/social features (VN Decree 147/2024 compliance) - All widgets are merchant-controlled or read-only