Skip to main content

Build widget apps and embedded experiences

Widget apps turn the Messenger home screen into a small support surface, not just a launcher for chat.

Instead of sending customers to another tab, you can open an embedded page directly inside the widget for common tasks like watching a walkthrough, booking time with support, or viewing account-specific information.

For supported status providers, OXVO can go one step further and render the current status directly on the widget home screen, then open a native status detail view inside the widget instead of a generic iframe.

OXVO now does the same kind of upgrade for a small set of provider templates where the official provider model supports it cleanly:

  • Calendly and Cal.com can open as inline booking flows inside the widget app view.
  • Mailchimp can use a public hosted signup form URL to render a native email-first subscribe step in the widget.
  • Typeform and Survicate can carry visitor context into the embedded form URL when the provider supports hidden fields or visitor attributes.

Where to configure widget apps

Open:

  • Settings → Integrations → Channels
  • Choose your Website inbox
  • Go to User Engagement → Applications

From there you can start with a template, save reusable apps to your library, and turn them on for a specific widget.

Good widget app use cases

The best widget apps solve a focused job in a few seconds:

  • Walkthrough video: product tour, setup checklist, or troubleshooting clip
  • Booking flow: onboarding session, office hours, renewal call, or escalation booking
  • Status update: outage banner, maintenance page, or uptime dashboard
  • Feedback capture: bug report, NPS, feature request, or churn survey
  • Personalized portal: account summary, order tracker, billing view, onboarding progress

If the experience needs deep navigation or a full application shell, link out instead of forcing the widget to behave like a full product workspace.

Native status integrations

OXVO supports a more integrated status experience for:

  • Atlassian Statuspage
  • Better Stack
  • Instatus

These templates behave differently from a normal embedded app:

  • The current status is shown directly on the widget home screen
  • Clicking the app opens a native detail view with incidents, maintenance, and service health
  • Visitors can still open the full provider status page when they need deeper history or subscription options

Behind the scenes, OXVO reads each provider's public status feed:

  • Atlassian Statuspage: /api/v2/summary.json
  • Better Stack: /index.json
  • Instatus: /summary.json

Use Custom status page when you want to embed your own status or incident page as a regular iframe app. Use one of the provider templates above when you want the smoother, native status experience.

How embedded apps receive visitor context

When a visitor opens an iframe-based widget app, OXVO loads your app inside an iframe and posts a message to it.

Current event shape:

{
source: 'oxvo-app',
type: 'oxvo.current_user',
payload: {
id: 42,
identifier: 'customer_123',
email: 'customer@example.com',
name: 'Customer Name',
phone_number: '+1 555 010 1000'
}
}

This payload is intentionally lightweight. In practice, the most useful fields are:

  • id: internal OXVO contact id
  • identifier: your external user identifier if you set one through Messenger SDK identity
  • email, name, phone_number: visitor details you can use for prefill, lookup, or fallback UX

For personalized widget apps, do not depend on the iframe payload alone to render everything.

A stronger pattern is:

  1. Listen for oxvo.current_user
  2. Read payload.identifier or payload.id
  3. Call your own backend
  4. Render account, order, billing, or onboarding data from your source of truth

That keeps the widget payload small while still letting you build useful customer-facing tools.

Listener example

<script>
window.addEventListener('message', async event => {
const message = event.data || {};

if (message.source !== 'oxvo-app') return;
if (message.type !== 'oxvo.current_user') return;

const visitor = message.payload || {};
const lookupKey = visitor.identifier || visitor.id;
if (!lookupKey) return;

const response = await fetch(
`/api/widget-portal?key=${encodeURIComponent(lookupKey)}`
);
const account = await response.json();

renderAccountPortal(account);
});
</script>

Example: personalized billing or order portal

This is a strong fit for widget apps because the user is already in a support context.

A practical flow:

  • Visitor opens Account status or Track my order
  • Your page receives oxvo.current_user
  • Your app looks up the customer by identifier or id
  • You render invoices, shipment checkpoints, renewal details, or onboarding blockers
  • The customer stays inside the widget while your team remains one click away in chat

This works especially well for:

  • subscription billing questions
  • shipping or delivery updates
  • onboarding task completion
  • plan or seat usage checks

Example: embed-first apps that need no personalization

Some widget apps are useful even without visitor lookup:

  • YouTube or Vimeo walkthroughs
  • Loom answer videos
  • changelog or release note pages
  • native status integrations for Statuspage, Better Stack, or Instatus
  • custom status pages
  • booking pages
  • feedback forms

These are often the fastest apps to launch because they only need an embed-friendly URL plus a clear title and description.

Provider-ready templates

OXVO also ships provider-focused templates for teams that want faster setup around common SaaS tools:

  • Calendly and Cal.com for booking demos, onboarding, or escalation calls
  • Mailchimp for newsletter signup and waitlists
  • Typeform and Survicate for intake forms, surveys, CSAT, or research
  • Canny and Featurebase for feedback boards, roadmap visibility, and changelogs
  • Document360 and HelpDocs for self-serve help center search and troubleshooting

Most templates still use the lightweight iframe app model. In practice that means:

  • OXVO stores the public URL, app title, description, and optional image
  • The widget opens the configured page inside a lightweight Messenger app shell with refresh and browser fallback actions
  • The admin setup flow links directly to the provider's implementation docs

By default, you can keep the visitor-facing title generic, such as Book a meeting or Search our docs, even when the template itself is provider-specific in the admin UI.

Providers with a more native widget runtime

Some provider templates now go beyond a plain iframe because the provider supports a better public embed model:

  • Calendly: opens as an inline booking embed and can prefill visitor name and email.
  • Cal.com: opens as an inline booking embed and can prefill visitor name, email, and metadata.
  • Mailchimp: uses a hosted signup form URL to prepare a native email-first subscribe flow inside the widget. OXVO reads the public form details Mailchimp exposes for custom signup forms. No Mailchimp API key is required for this setup.
  • Typeform: keeps the lightweight embed shell, but OXVO can append visitor fields such as email and identifier as URL parameters for hidden fields when your form supports them.
  • Survicate: keeps the lightweight embed shell, but OXVO can append visitor attributes such as user-id, name, and email to the survey URL.

Keep secrets and signed access out of widget config

Do not paste provider API keys, workspace secrets, admin URLs, or signed embed tokens into widget app settings.

For iframe-based provider apps, a safer pattern is:

  1. Keep auth, API calls, and token generation on your own backend
  2. Expose a public or authenticated page that you control
  3. Point the widget app at that page

That keeps the messenger runtime lightweight and prevents sensitive provider credentials from being exposed to visitors.

This matters most for apps that may need authenticated access, such as:

  • feedback portals with signed identity
  • private help centers
  • booking flows with custom routing logic
  • subscribe forms or surveys tied to account-level permissions

Mailchimp setup note

For the native Mailchimp widget flow, use a hosted signup form URL from Mailchimp.

OXVO reads the public form action and audience fields that Mailchimp exposes for custom signup forms, then uses that public setup to render a native subscribe experience in the widget.

Do not paste:

  • Mailchimp Marketing API keys
  • admin-only Mailchimp URLs
  • private audience management links

Production guidelines

  • Keep iframe apps lightweight. Widget apps open in a compact mobile-sized surface.
  • If you use a native status integration, confirm the provider exposes a stable public JSON feed and that the public page URL is correct.
  • Make sure iframe-based providers allow iframe embedding. Many public pages still block iframes.
  • Validate event.origin if your app is exposed on the public internet.
  • Do not put secrets in the iframe page or depend on frontend-only authorization for sensitive account data.
  • Treat identifier as the preferred lookup key when you already identify users through Messenger SDK.
  • Provide a graceful empty state for anonymous visitors when no identifier is available yet.

Launch checklist

  • Does the page render well at widget size on desktop and mobile?
  • If this is an iframe app, does the provider allow iframe embedding in production?
  • If this is a native status integration, does the public status feed resolve correctly from the real widget?
  • Does your app handle missing identifier or id safely?
  • Is the first screen focused on one support job instead of a full navigation tree?
  • Have you tested the open flow from the real widget, not just the standalone page?