Native Utilities

Haptic feedback, sounds, URLs, app reviews, and more inside your flows.

haptic()#

Trigger haptic feedback on the device. Falls back to vibration on devices without haptic motors.

Mobana.haptic(style: HapticStyle): void
ParameterTypeDescription
styleRequiredHapticStyleImpact style: light, medium, heavy
Notification style: success, warning, error
Selection: selection
flow.js
// Feedback for button taps
document.querySelectorAll('button').forEach(btn => {
  btn.addEventListener('click', () => {
    Mobana.haptic('light');
  });
});

// Success feedback
function onSuccess() {
  Mobana.haptic('success');
}

// Error feedback
function onError() {
  Mobana.haptic('error');
}

// Selection feedback (e.g., picker changes)
document.querySelectorAll('input[type="radio"]').forEach(radio => {
  radio.addEventListener('change', () => {
    Mobana.haptic('selection');
  });
});

Requires react-native-haptic-feedback to be installed. If not available, falls back to the Vibration API.

playSound()#

Play a sound from a URL or base64 data URL.

Mobana.playSound(url: string, options?: SoundOptions): SoundController
ParameterTypeDescription
urlRequiredstringSound URL (https://...) or base64 data URL (data:audio/mp3;base64,...)
volumenumber= 1.0Volume level (0.0 to 1.0)
loopboolean= falseWhether to loop the sound
onEnd() => voidCallback when sound finishes playing
onError(error) => voidCallback when an error occurs
PropertyTypeDescription
isPlayingbooleanWhether sound is currently playing
stop()functionStop playback
flow.js
// Play a success sound
const sound = Mobana.playSound('https://example.com/success.mp3');

// With options
const sound = Mobana.playSound('https://example.com/music.mp3', {
  volume: 0.5,      // 50% volume
  loop: true,       // Loop the sound
  onEnd: () => {
    console.log('Sound finished');
  },
  onError: (error) => {
    console.log('Sound failed:', error);
  },
});

// Control playback
console.log(sound.isPlaying);  // true
sound.stop();                  // Stop playback

Base64 Sounds (No Network)

// Play a base64-encoded sound (no network request needed)
const sound = Mobana.playSound('data:audio/mp3;base64,SUQzBAAAAAAAI1RTU0...');

For critical sounds (success, error), consider using base64 data URLs to avoid network latency. Keep sounds short (under 100KB).

openURL()#

Open a URL in the device's default browser.

Mobana.openURL(url: string): void
flow.js
// Open external link
document.getElementById('learn-more-btn').addEventListener('click', () => {
  Mobana.openURL('https://example.com/learn-more');
});

// Open app store
document.getElementById('rate-app-btn').addEventListener('click', () => {
  const platform = Mobana.getPlatform();
  const storeUrl = platform === 'ios'
    ? 'https://apps.apple.com/app/id123456789'
    : 'https://play.google.com/store/apps/details?id=com.example.app';
  Mobana.openURL(storeUrl);
});

openSettings()#

Open the app's settings page. Useful when permissions are blocked.

Mobana.openSettings(): void
// When user needs to enable permission in settings
document.getElementById('open-settings-btn').addEventListener('click', () => {
  Mobana.openSettings();
});

requestAppReview()#

Request an app store review. Shows the native review dialog.

Mobana.requestAppReview(): void
Important: Completes the Flow

Due to iOS StoreKit limitations, the review dialog cannot be shown while a modal (the flow) is visible. Calling requestAppReview() will complete the flow and then show the review dialog.

Use this as the final action in your flow.

flow.js
// Request app store review at the end of a positive flow
document.getElementById('love-it-btn').addEventListener('click', () => {
  Mobana.trackEvent('positive_feedback');
  
  // This will complete the flow AND show review dialog
  Mobana.requestAppReview();
});

// Alternative: Just complete without review
document.getElementById('not-now-btn').addEventListener('click', () => {
  Mobana.complete();
});

Requires react-native-in-app-review to be installed. If not available, the flow will complete without showing the review dialog.

Best Practices#

  • Use haptics sparingly: Provide feedback for important actions, not every tap.
  • Match haptic to action: Use success for completions, error for failures, selection for choices.
  • Request reviews strategically: Ask after positive moments (completed onboarding, achieved goal), not randomly.
  • Keep sounds short: Under 2 seconds for UI feedback sounds.