Skip to main content
Monigo ships first-class UI packages for React, Vue, Svelte, and Flutter. Each one embeds the full customer portal — invoices, subscriptions, wallets, payout accounts, payment methods — directly in your app, styled to match your brand, with a single portal-token prop. Use these packages when you want the customer experience to live inside your product rather than redirecting to the hosted portal at monigo.co/portal/<token>. All four deliver the same building blocks (invoice list, wallet card, subscription card, etc.) and the same opinionated composed portal (<MonigoPortal />). They share a common core: @monigo/portal-core (typed API client + state machines) and @monigo/tokens (CSS variables and theming helpers).

How it fits together

Your backend generates a portal token (see Customer Portal). Your frontend drops in <MonigoPortal /> with that token. Done.
Generate portal tokens server-side. Never expose your Monigo API key to the browser. See Security considerations.

Install

The TS packages have zero runtime dependencies beyond their peer framework. No CSS-in-JS, no Tailwind, no router lock-in. Monigo’s design tokens ship as plain CSS variables.

Quick start (the 5-minute integration)

The flow is always the same:
  1. Your backend mints a portal token and hands it to your frontend.
  2. Your frontend renders <MonigoProvider> with the token and drops in <MonigoPortal />.

1. Mint the token on your server

Node.js / Server

2. Render the portal on the client

That’s the entire integration. <MonigoPortal /> renders its own navigation, routing, and all feature pages — dashboard, invoices, bills, subscriptions, wallets, payment methods, payout accounts.

Building-block composition

If you want the data and behaviour but not the opinionated layout, use the building-block components directly. They share the same <MonigoProvider> context and run independently.
Every building block handles its own loading, empty, and error states. Each fetches independently and refetches on window focus after 30 seconds.

Exported building blocks

The same component names exist across React, Vue, and Svelte. Flutter widgets follow Dart’s snake_case → Pascal convention (InvoiceList, invoice_list.dart).

Theming

Monigo’s components render against a set of CSS custom properties. The defaults are sensible; the ones you usually want to change are primary, accent, and mode.

Quick theming via props

mode accepts 'light', 'dark', or 'auto'. With auto, the portal follows the user’s system preference via prefers-color-scheme.

Full theme API (web packages)

Theming via CSS (any host app)

Every token is a plain CSS variable. Override any of them on any ancestor element:
Want the full list? It’s in @monigo/tokens/monigo.css — or use the typed TOKEN_NAMES array:

Runtime theme generation (per-tenant)

If you render the portal for multiple tenants with different brand colors, inject a scoped theme at runtime:

Using your own router

The <MonigoPortal /> component bundles a lightweight internal router so the 5-minute demo stays a one-liner. For production apps that already have a router (Next.js App Router, Nuxt, SvelteKit, Remix, TanStack Router), import the page components and wire them into your own routes.

Exported page components


Customer actions

Every action component fires an optional onError callback for telemetry and emits a success callback you can use to refresh state or navigate.

Pay an invoice

React
Clicking PayInvoiceButton calls POST /portal/invoices/:id/pay, which returns a gateway authorization_url. The component redirects the browser to that URL automatically.

Cancel a subscription

Svelte
Cancellation requires user confirmation via window.confirm. The backend call happens only after confirmation.

Add a payment method

Vue
The add flow redirects to the payment gateway’s tokenization page (Paystack today). If your Monigo organisation uses a gateway that doesn’t yet support stored-card setup, the component emits unsupported and shows a localized message.

Wallet top-ups

Flutter
Opens an inline amount input, calls POST /portal/wallets/:id/fund, and redirects to the gateway.

Error handling

Every component renders three states out of the box: loading (skeleton), empty (“you have no invoices yet”), and error (with a Try again button). You can override any of them.
For a global handler (telemetry, Sentry, unauthorized-token redirect), use the provider:

SSR & server components

All web packages are SSR-safe. The components don’t touch window, document, or localStorage at module scope — only inside framework lifecycle hooks.
The portal fetches data on the client regardless — portal tokens are customer-scoped and we don’t want them pre-fetched on a shared cache. The initial HTML shows skeletons; the data streams in after hydration.

i18n

v1 ships English. All user-visible strings live in a typed catalog you can override:
React
Every key comes with a sensible default. The full list is exported as the MessageKey union from @monigo/portal-core.

Proxying the API (advanced)

By default, every component calls https://api.monigo.co/api/v1/portal/* directly from the browser with the X-Portal-Token header. If your security policy requires all traffic to flow through your own backend, pass a custom baseUrl and fetch:
Then set up a lightweight reverse proxy on your server that forwards /api/monigo/* to https://api.monigo.co/api/v1/* and injects the X-Portal-Token header (or validates one from a cookie you control).

Bundle size

Tree-shaking works end-to-end. A minimal integration (provider + InvoiceList only) ships well under 20 kB min+gzip in React, Vue, and Svelte. The full <MonigoPortal /> is under 60 kB min+gzip per framework. Flutter’s monigo_portal adds roughly 450 kB to release APKs (mostly from generated models). It uses dart:http — no extra native plugins — so it compiles unchanged for iOS, Android, web, macOS, Linux, and Windows.

Publishing targets

The web packages use synchronised versioning — they bump together via Changesets. Flutter ships its own cadence.