Micro‑App Developer Guide
This guide shows you how to build, test, package, and publish a web Micro‑App that runs inside the Super App's WebView.
New to MicroApps? Start with Bridge Overview to understand the fundamentals.
Ready to build? Jump to Quickstart for a quick example.
Quickstart (Hello Micro‑App)
1. Scaffold a web app (any framework works). Example: React + Vite
2. Add safe bridge access and a simple call
// src/App.tsx
import { useEffect, useState } from "react";
export default function App() {
const [tokenPreview, setTokenPreview] = useState<string | undefined>();
// Detect if running inside the SuperApp host
const inHost = typeof (window as any).nativebridge?.requestToken === "function";
useEffect(() => {
const run = async () => {
if (!inHost) return;
try {
// Request a token from the host using the bridge
const token = await (window as any).nativebridge.requestToken();
setTokenPreview(token ? token.slice(0, 12) + "…" : undefined);
} catch (e) {
console.error("requestToken failed", e);
}
};
run();
}, [inHost]);
return (
<main style={{ padding: 24 }}>
<h1>My Micro‑App</h1>
<p>Host detected: {inHost ? "Yes" : "No (browser preview)"}</p>
<p>Token: {tokenPreview ?? "—"}</p>
<button
onClick={async () => {
try {
// Request an alert from the host
await (window as any).nativebridge?.requestAlert?.({
title: "Hello",
message: "Welcome!",
buttonText: "OK",
});
} catch (e) {
console.log("Alert not available in browser preview");
}
}}
>
Say Hi
</button>
</main>
);
}
3. Run locally for browser preview
Optional: Add a tiny bridge polyfill for browser preview (no host), so your code doesn’t crash:
// src/bridge-polyfill.ts (import it in main.tsx during local dev only)
declare global {
interface Window {
nativebridge?: any;
}
}
if (!window.nativebridge) {
window.nativebridge = {
requestToken: async () => null,
requestAlert: async ({ title, message }: any) => {
// Browser fallback
alert(`${title}: ${message}`);
},
};
}
Later, you’ll build a ZIP and publish via the Admin Portal so the Super App can download and run it.
Bridge overview
Since Micro-apps run in a isolated webview container, to communicate with the host it is using a lightweight promise-based bridge exposed on window.nativebridge.
Replace <bridgeFunction> with the specific method you need.
Note
- See Available Bridge Methods
- All bridge calls are async; always use try/catch.
- If a request fails, the promise rejects with an error string.
Naming and conventions
- Request method names follow the
requestXxxpattern (e.g.requestUserId,requestToken). - The host generates corresponding
resolveXxx/rejectXxxhandler names automatically; micro-apps only need to callrequestXxx. - Avoid touching
window.nativebridge._pendingPromisesor internal fields — only use the documented request functions.
How to detect the host vs stand-alone web mode
When running in a WebView inside the host, window.nativebridge will be available. Protect your code when running in a normal browser:
const inHost = typeof window.nativebridge?.requestToken === "function";
if (inHost) {
const token = await window.nativebridge.requestToken();
} else {
// fallback behavior for standalone web preview
}
Packaging & metadata
1. Build your app for production
Your output directory will typically be dist/ (Vite) or build/ (CRA):
2. Add a microapp.json file at the ROOT of the built output directory with these fields:,
{
"name": "Micro App Name",
"description": "A brief description of the micro app",
"appId": "unique-app-id",
"clientId": "client-id-for-authentication-if-integrated",
"displayMode": "Controls whether to hide the header ('fullscreen') or show it ('default'). If no value is provided, it defaults to 'default'"
}
Field notes
-
appId: unique, URL‑safe identifier (e.g., "calendar", "com.example.payroll"). Use for determining micro-app identity. Which you'll receive from Super App Admin.
-
clientId: OAuth2 client ID of the microapp if superapp use external IdP for authentication. otherwise, same as appId.
-
displayMode: "default" (shows header) or "fullscreen" (no header, manage your own safe areas).
-
Package as a ZIP
-
Important: ZIP the CONTENTS of the build folder, not the folder itself.
- Good: index.html, assets/, microapp.json at the root of the ZIP
- Bad: my-app-dist/index.html (nested path inside the ZIP)
To Publish via Admin Portal Contact the Adminstrator of the system.
Local development tips
- Iterate UI in the browser with the bridge polyfill; package/upload when you need to test real bridge flows on device.
- If your API requires auth, use
requestToken()from the host when running inside the app; in browser preview, use a test token or mock responses, but never bundle tokens with the app. - Keep CORS minimal; ensure your APIs are reachable from the device running the Super App.
Security guidance (important)
- Tokens may expire or be revoked at any time—always request fresh tokens when needed rather than caching them long-term. Follow least-privilege: request only what you need.
- Avoid storing long‑lived secrets in plain text inside the micro‑app. Use the Super App’s token exchange (
requestToken) which returns a token scoped for the micro‑app. - Validate any sensitive operations on the backend; do not rely on client-side checks alone.
Testing and debugging
- If a bridge request hangs, check native logs to confirm the handler ran and the promise was resolved/rejected.
Pre‑publish checklist
-
microapp.jsonpresent at ZIP root and valid - appId is unique and URL‑safe
- version/build updated (build strictly increases)
- icon/banner reachable (HTTPS)
- bridge calls guarded for browser preview
- no secrets committed in source or shipped assets
Common pitfalls
- Calling
window.nativebridge.requestXxxwithout guarding for existence when previewing in a normal browser will throw. Always detectwindow.nativebridge. - Expect Promise rejections. Wrap in try/catch.