Skip to main content
When your webview runs inside the MentraOS Mobile App, it has access to native capabilities through the bridge API. These functions work seamlessly in MentraOS and fall back to browser equivalents when your app is opened in a regular browser.

Installation

The bridge API is included in the @mentra/react package:
npm install @mentra/react

Quick Start

import { useMentraBridge } from '@mentra/react';

function MyApp() {
  const bridge = useMentraBridge();

  return (
    <div>
      <p>Running in MentraOS: {bridge.isInMentraOS ? 'Yes' : 'No'}</p>
      <p>Platform: {bridge.platform ?? 'browser'}</p>
      <button onClick={() => bridge.share({ text: 'Hello from my app!' })}>
        Share
      </button>
    </div>
  );
}

Environment Detection

isInMentraOS()

Check if your app is running inside the MentraOS webview.
import { isInMentraOS } from '@mentra/react';

if (isInMentraOS()) {
  // Running inside MentraOS Mobile App
} else {
  // Running in a regular browser
}

getMentraOSPlatform()

Get the host platform.
import { getMentraOSPlatform } from '@mentra/react';

const platform = getMentraOSPlatform();
// 'ios' | 'android' | null (null when not in MentraOS)

hasCapability(capability)

Check if a specific bridge capability is available.
import { hasCapability } from '@mentra/react';

if (hasCapability('share')) {
  // Native share sheet is available
}
Available capabilities: 'share', 'open_url', 'copy_clipboard', 'download'

Share

Open the native share sheet. Supports text, URLs, and files.
import { share } from '@mentra/react';

// Share text
await share({ text: 'Check this out!' });

// Share a URL
await share({ url: 'https://example.com', title: 'Example' });

// Share a file (base64)
await share({
  base64: pdfBase64,
  mimeType: 'application/pdf',
  filename: 'notes.pdf',
});
Returns Promise<BridgeResponse> with { success, cancelled?, error? }. Browser fallback: Uses navigator.share() if available, otherwise copies text to clipboard.

ShareOptions

PropertyTypeDescription
textstring?Plain text to share
titlestring?Title shown in the share sheet
urlstring?URL to share
base64string?Base64-encoded file data
mimeTypestring?MIME type when sharing a file
filenamestring?Filename when sharing a file

Open URL

Open a URL in the system browser, escaping the webview.
import { openUrl } from '@mentra/react';

openUrl('https://example.com');
Browser fallback: window.open(url, '_blank').

Copy to Clipboard

Copy text to the system clipboard.
import { copyToClipboard } from '@mentra/react';

const success = await copyToClipboard('Copied text!');
Returns Promise<boolean>true if the copy succeeded. Browser fallback: navigator.clipboard.writeText().

Download

Download a file. In MentraOS, this writes the file and opens the share sheet so the user can save it.
import { download } from '@mentra/react';

// Download from base64
await download({
  base64: pdfBase64,
  mimeType: 'application/pdf',
  filename: 'report.pdf',
});

// Download from URL
await download({
  url: 'https://example.com/file.pdf',
  filename: 'file.pdf',
});
Returns Promise<BridgeResponse> with { success, error?, filePath? }. Browser fallback: Creates a temporary download link.

DownloadOptions

PropertyTypeDescription
base64string?Base64-encoded file data
urlstring?URL to download from
mimeTypestring?MIME type of the file
filenamestringFilename for the downloaded file (required)

Capsule Menu

The capsule menu is the floating pill in the top-right corner of miniapp webviews (containing the ... menu and close button). It renders on top of your content, so you need to account for it in your layout.
Capsule menu position

useCapsuleMenu()

React hook that returns the capsule menu’s bounding rect and a convenience safeAreaTop value.
import { useCapsuleMenu } from '@mentra/react';

function MyApp() {
  const { safeAreaTop } = useCapsuleMenu();

  return (
    <div style={{ paddingTop: safeAreaTop }}>
      {/* Content won't overlap the capsule menu */}
    </div>
  );
}
Returns { rect: CapsuleMenuRect | null, safeAreaTop: number }
  • rect — the bounding box of the capsule menu, or null outside MentraOS
  • safeAreaTop — minimum top padding (in px) to clear the capsule menu. 0 outside MentraOS.

getCapsuleMenuRect()

Standalone function (no React required). Returns the capsule menu’s bounding rect relative to the webview content area.
import { getCapsuleMenuRect } from '@mentra/react';

const rect = getCapsuleMenuRect();
if (rect) {
  console.log(`Capsule: top=${rect.top} right=${rect.right} ${rect.width}x${rect.height}`);
}
Returns CapsuleMenuRect | null

CapsuleMenuRect

PropertyTypeDescription
topnumberDistance from top of webview content (px)
rightnumberDistance from right edge of screen (px)
bottomnumberBottom edge = top + height (px)
leftnumberLeft edge (px)
widthnumberWidth of the capsule menu (px)
heightnumberHeight of the capsule menu (px)

Custom Navigation Bar

If you want to build a custom nav bar that sits beside the capsule (like WeChat mini programs), use the raw rect:
import { useCapsuleMenu } from '@mentra/react';

function CustomNavBar({ title }: { title: string }) {
  const { rect } = useCapsuleMenu();
  const navHeight = rect ? rect.bottom + 8 : 48;
  const navPaddingTop = rect?.top ?? 8;

  return (
    <nav style={{
      height: navHeight,
      paddingTop: navPaddingTop,
      paddingLeft: 16,
      paddingRight: rect ? rect.width + rect.right + 16 : 16,
      display: 'flex',
      alignItems: 'center',
    }}>
      <h1>{title}</h1>
      {/* Capsule menu floats to the right of this */}
    </nav>
  );
}

useMentraBridge() Hook

Convenience hook that bundles all bridge capabilities:
import { useMentraBridge } from '@mentra/react';

function MyComponent() {
  const bridge = useMentraBridge();

  // bridge.isInMentraOS  — boolean
  // bridge.platform      — 'ios' | 'android' | null
  // bridge.hasCapability — (capability: string) => boolean
  // bridge.share         — (options: ShareOptions) => Promise<BridgeResponse>
  // bridge.openUrl       — (url: string) => void
  // bridge.copyToClipboard — (text: string) => Promise<boolean>
  // bridge.download      — (options: DownloadOptions) => Promise<BridgeResponse>
}

Browser Fallbacks

Every bridge function gracefully falls back when running outside MentraOS:
FunctionMentraOSBrowser Fallback
share()Native share sheetnavigator.share() then clipboard
openUrl()System browserwindow.open()
copyToClipboard()Native clipboardnavigator.clipboard
download()Save via share sheetDownload link
getCapsuleMenuRect()Bounding rectnull
useCapsuleMenu(){ rect, safeAreaTop }{ null, 0 }
This means you can develop and test your webview in a regular browser, and it will work correctly when opened inside MentraOS.