Create Free APK

JavaScript bridge API

Home-screen widget

A small Android card on the home screen that your page fills with a title, a value and a few lines - AppMint.widget.

AppMint.widget helper#

AppMint.widget.set(card) / clear() / placedCount() / requestPin()

Example

Fills your app's home-screen widget: a small native card with a title, one big value, up to six short lines, your colours, and a route that a tap opens. A widget cannot show HTML - you send it the text.

Returns: every method returns a Promise. set(card){ok: true, placed} (placed = how many copies are on the home screen) or {ok: false, error}. clear()undefined. placedCount() → a number. requestPin()true if the launcher's "Add" sheet opened. Needs: nothing - every build has the widget.

Set the card - once at start, and again every time the data it shows changes:

async function updateWidget(events) {
  if (!(window.AppMint && AppMint.widget)) return;          // in a browser
  var r = await AppMint.widget.set({
    title: 'Today',
    value: events.length + ' events',
    lines: events.slice(0, 6).map(function (ev) { return ev.time + ' ' + ev.name; }),
    route: '/calendar',      // a tap opens the app at this route
    bg: '#0E7C86',           // background
    ink: '#FFFFFF',          // title and lines
    accent: '#FFE08A'        // the big value
  });
  if (!r.ok) console.log('Widget not updated: ' + r.error);
}

An "Add to home screen" button:

async function addWidget() {
  if (!(window.AppMint && AppMint.widget)) return;
  if ((await AppMint.widget.placedCount()) > 0) { alert('The widget is already on your home screen'); return; }
  var opened = await AppMint.widget.requestPin();
  if (!opened) alert('Touch and hold your home screen, tap Widgets, and pick this app.');
}

Empty it (for example after the user signs out):

if (window.AppMint && AppMint.widget) AppMint.widget.clear();   // shows "Nothing to show yet"

A tap on the widget opens the app with appmint-shortcut://<package><route> as its launch link - read it with WebToApk.getLaunchUrl() on start and the appmint:deep-link event while running:

window.addEventListener('appmint:deep-link', function (e) {
  var m = /^appmint-shortcut:\/\/[^\/?#]*([^#]*)/i.exec(e.detail.url);
  if (m) goTo(m[1] || '/');
});

Notes: All card fields are optional: an empty title shows the app name; empty value or lines are hidden; lines after the sixth are dropped; colours are #RRGGBB / #AARRGGBB (a bad colour uses the default). The widget keeps the last card, even after a restart, and changes only when your page calls set() again. requestPin() needs Android 8+ and a launcher that supports it. AI-built apps can use widget from @/lib/appmintNative. Website-mode apps: a widget tap restarts the app, and in Website mode the shell then tries to load the appmint-shortcut:// address as a page, which fails (the WebView cannot open that kind of address) - so a tap route only works in HTML, ZIP and AI-built apps.

widgetClear bridge#

window.WebToApk.widgetClear()

Removes the card; placed widgets go back to their empty state.

Example

Internal plumbing behind AppMint.widget.clear() - removes the widget's card; every placed widget goes back to "Nothing to show yet".

Returns: nothing. Needs: nothing.

The public API first:

async function onSignOut() {
  if (window.AppMint && AppMint.widget) await AppMint.widget.clear();
}

The raw call:

if (window.WebToApk && typeof window.WebToApk.widgetClear === 'function') {
  window.WebToApk.widgetClear();
}

Notes: The widget stays on the home screen; only its content is removed. Call AppMint.widget.set() to fill it again.

widgetPlacedCount bridge#

window.WebToApk.widgetPlacedCount(): Int

How many copies of the widget the user has placed on the home screen.

Example

Internal plumbing behind AppMint.widget.placedCount() - how many copies of your widget the user has put on the home screen.

Returns: a number, synchronously (0 when none). Needs: nothing.

The public API first - show an "Add widget" button only when the widget is not placed yet:

async function showAddWidgetButton() {
  var btn = document.getElementById('add-widget');
  if (!(window.AppMint && AppMint.widget)) { btn.hidden = true; return; }
  btn.hidden = (await AppMint.widget.placedCount()) > 0;
}

The raw call:

if (window.WebToApk && typeof window.WebToApk.widgetPlacedCount === 'function') {
  var n = window.WebToApk.widgetPlacedCount();
  console.log('Widgets on the home screen: ' + n);
}

Notes: Check it again when the app comes back to the front (visibilitychange), since the user adds widgets from the launcher, outside your app.

widgetRequestPin bridge#

window.WebToApk.widgetRequestPin(): Boolean

Opens the launcher's "Add to home screen" sheet for the widget (Android 8+). False where the launcher cannot.

Example

Internal plumbing behind AppMint.widget.requestPin() - opens the launcher's "Add to home screen" sheet for your widget.

Returns: true if the sheet opened, false where the launcher cannot (synchronously). Needs: Android 8+ and a launcher that supports pinning widgets.

The public API first, from a button tap:

document.getElementById('add-widget').onclick = async function () {
  if (!(window.AppMint && AppMint.widget)) return;
  var opened = await AppMint.widget.requestPin();
  if (!opened) {
    alert('Touch and hold your home screen, tap Widgets, then pick this app.');
  }
};

The raw call:

if (window.WebToApk && typeof window.WebToApk.widgetRequestPin === 'function') {
  if (!window.WebToApk.widgetRequestPin()) showManualSteps();
}

Notes: true only means the sheet opened - the user can still cancel it. Use AppMint.widget.placedCount() later to see whether it was added. Fill the card with AppMint.widget.set() first, so the new widget is not empty.

widgetSet bridge#

window.WebToApk.widgetSet(cardJson: String): String

Saves the widget card [cardJson] `{title?, value?, lines?, route?, bg?, ink?, accent?}` and redraws every placed widget. Returns `{ok, placed}`.

Example

Internal plumbing behind AppMint.widget.set(card) - pages use that helper to fill the home-screen widget.

Returns: a JSON string {"ok":true,"placed":<number>} or {"ok":false,"error":"…"} (synchronously). Needs: nothing - every build has the widget.

The public API first:

if (window.AppMint && AppMint.widget) {
  AppMint.widget.set({ title: 'Steps', value: '8 214', lines: ['Goal 10 000'], route: '/' })
    .then(function (r) { if (!r.ok) console.log(r.error); });
}

The raw call takes the card as a JSON string and returns JSON text:

if (window.WebToApk && typeof window.WebToApk.widgetSet === 'function') {
  var card = { title: 'Steps', value: '8 214', lines: ['Goal 10 000'], route: '/',
               bg: '#15161A', ink: '#FFFFFF', accent: '#22D3EE' };
  var r = JSON.parse(window.WebToApk.widgetSet(JSON.stringify(card)));
  console.log(r.ok ? 'on ' + r.placed + ' home screen(s)' : r.error);
}

Notes: Card keys: title, value, lines (up to six), route (a / is added if missing), bg, ink, accent. Every placed widget redraws at once. placed is 0 when the user has not added the widget yet - the card is still saved and appears when they do.

Generated from the app runtime and its example files on every docs build. Read it as Markdown · All families.

Checked against the shipped bridge on 2026-09-23.