Skip to main content

Hooks API

The @54vie/miniapp-sdk provides React hooks that allow mini-apps to interact with host app services in a declarative way. All hooks automatically handle cleanup and state synchronization.

useHostAuth

Access authentication state and methods from the host app.

TypeScript Interface

interface User {
id: string;
name: string;
avatar?: string;
phone?: string;
email?: string;
}

interface HostAuthState {
/** Current authenticated user object, null if not logged in */
user: User | null;
/** Whether the user is currently authenticated */
isAuthenticated: boolean;
/** Get a fresh access token for API calls */
getAccessToken: () => Promise<string>;
}

function useHostAuth(): HostAuthState;

Return Value

PropertyTypeDescription
userUser | nullCurrent user object or null if not authenticated
isAuthenticatedbooleanWhether the user is logged in
getAccessToken() => Promise<string>Async function to retrieve a valid JWT token

Example

import { useHostAuth } from '@54vie/miniapp-sdk';

function ProfileScreen() {
const { user, isAuthenticated, getAccessToken } = useHostAuth();

const fetchUserData = async () => {
const token = await getAccessToken();
const response = await fetch('/api/user/profile', {
headers: { Authorization: `Bearer ${token}` },
});
return response.json();
};

if (!isAuthenticated) {
return <Text>Please login to continue</Text>;
}

return (
<View>
<Text>Welcome, {user?.name}!</Text>
<Text>Email: {user?.email}</Text>
</View>
);
}

useHostDevice

Access device information and hardware capabilities.

TypeScript Interface

interface DeviceInfo {
deviceId: string;
deviceName: string;
platform: 'ios' | 'android';
model: string;
brand: string;
osVersion: string;
appVersion: string;
buildNumber: string;
isEmulator: boolean;
isTablet: boolean;
}

interface BatteryInfo {
level: number; // 0-100
isCharging: boolean;
isLowPowerMode: boolean;
}

interface HostDeviceState {
info: DeviceInfo | null;
battery: BatteryInfo | null;
isLoading: boolean;
error: Error | null;
}

interface UseHostDeviceReturn extends HostDeviceState {
/** Refresh device information */
refresh: () => Promise<void>;
/** Get unique device ID */
getDeviceId: () => Promise<string>;
/** Get unique installation ID */
getUniqueId: () => Promise<string>;
/** Get mobile carrier name */
getCarrier: () => Promise<string | null>;
/** Check if device is a tablet */
isTablet: () => Promise<boolean>;
/** Check if running on emulator/simulator */
isEmulator: () => Promise<boolean>;
}

function useHostDevice(): UseHostDeviceReturn;

Return Value

PropertyTypeDescription
infoDeviceInfo | nullComplete device information
batteryBatteryInfo | nullBattery status information
isLoadingbooleanLoading state
errorError | nullError if fetch failed
refresh() => Promise<void>Refresh all device info
getDeviceId() => Promise<string>Get device identifier
getUniqueId() => Promise<string>Get installation identifier
getCarrier() => Promise<string | null>Get carrier name
isTablet() => Promise<boolean>Check if tablet
isEmulator() => Promise<boolean>Check if emulator

Example

import { useHostDevice } from '@54vie/miniapp-sdk';

function DeviceInfoComponent() {
const { info, battery, isLoading, refresh } = useHostDevice();

if (isLoading) return <ActivityIndicator />;

return (
<View>
<Text>Brand: {info?.brand}</Text>
<Text>Model: {info?.model}</Text>
<Text>OS: {info?.platform} {info?.osVersion}</Text>
<Text>Battery: {battery?.level}%</Text>
{battery?.isCharging && <Text>Charging</Text>}
<Button title="Refresh" onPress={refresh} />
</View>
);
}

useHostStorage

Access isolated key-value storage scoped to the mini-app.

TypeScript Interface

interface HostStorageState {
/** Get a value by key */
get: <T>(key: string) => Promise<T | null>;
/** Set a value for a key */
set: <T>(key: string, value: T) => Promise<void>;
/** Remove a value by key */
remove: (key: string) => Promise<void>;
/** Clear all storage for this mini-app */
clear: () => Promise<void>;
}

function useHostStorage(): HostStorageState;

Return Value

MethodTypeDescription
get<T>(key: string) => Promise<T | null>Retrieve a stored value
set<T>(key: string, value: T) => Promise<void>Store a value
remove(key: string) => Promise<void>Remove a stored value
clear() => Promise<void>Clear all mini-app storage

Example

import { useHostStorage } from '@54vie/miniapp-sdk';
import { useState, useEffect } from 'react';

interface CartData {
items: Array<{ id: string; qty: number }>;
}

function ShoppingCart() {
const { get, set, remove } = useHostStorage();
const [cart, setCart] = useState<CartData | null>(null);

useEffect(() => {
loadCart();
}, []);

const loadCart = async () => {
const savedCart = await get<CartData>('cart');
setCart(savedCart);
};

const addItem = async (productId: string) => {
const newCart: CartData = {
items: [...(cart?.items || []), { id: productId, qty: 1 }],
};
await set('cart', newCart);
setCart(newCart);
};

const clearCart = async () => {
await remove('cart');
setCart(null);
};

return (
<View>
<Text>Items in cart: {cart?.items.length || 0}</Text>
<Button title="Clear Cart" onPress={clearCart} />
</View>
);
}
Storage Scope

Each mini-app has its own isolated storage namespace. Data from one mini-app cannot be accessed by another.


useHostAnalytics

Track analytics events and screen views.

TypeScript Interface

interface HostAnalyticsState {
/** Track a custom event with optional properties */
trackEvent: (name: string, properties?: Record<string, unknown>) => void;
/** Track a screen view */
trackScreen: (screenName: string) => void;
}

function useHostAnalytics(): HostAnalyticsState;

Return Value

MethodTypeDescription
trackEvent(name: string, properties?: Record<string, unknown>) => voidTrack custom event
trackScreen(screenName: string) => voidTrack screen view

Example

import { useHostAnalytics } from '@54vie/miniapp-sdk';
import { useEffect } from 'react';

function ProductDetailScreen({ productId }: { productId: string }) {
const { trackEvent, trackScreen } = useHostAnalytics();

useEffect(() => {
trackScreen('ProductDetail');
trackEvent('product_viewed', {
productId,
timestamp: Date.now(),
});
}, [productId]);

const handleAddToCart = () => {
trackEvent('add_to_cart', {
productId,
quantity: 1,
source: 'product_detail',
});
// Add to cart logic
};

const handlePurchase = (amount: number) => {
trackEvent('purchase_completed', {
productId,
amount,
currency: 'VND',
});
};

return (
<View>
<Button title="Add to Cart" onPress={handleAddToCart} />
</View>
);
}
Attribution

All events from mini-apps are automatically attributed to the mini-app ID for analytics purposes.


useHostPush

Manage push notifications and local notifications.

TypeScript Interface

interface LocalNotification {
id?: string;
title: string;
body: string;
data?: Record<string, unknown>;
/** Schedule date (ISO string or timestamp) */
fireDate?: string | number;
/** Repeat interval */
repeatType?: 'minute' | 'hour' | 'day' | 'week' | 'month';
/** Badge number */
badge?: number;
/** Sound name */
sound?: string;
/** Android channel ID */
channelId?: string;
}

interface HostPushState {
token: string | null;
hasPermission: boolean;
badgeCount: number;
isLoading: boolean;
error: Error | null;
}

interface UseHostPushReturn extends HostPushState {
/** Refresh push notification state */
refresh: () => Promise<void>;
/** Request notification permission */
requestPermission: () => Promise<boolean>;
/** Set app badge count */
setBadgeCount: (count: number) => Promise<void>;
/** Clear app badge */
clearBadge: () => Promise<void>;
/** Subscribe to a topic (FCM) */
subscribeToTopic: (topic: string) => Promise<void>;
/** Unsubscribe from a topic */
unsubscribeFromTopic: (topic: string) => Promise<void>;
/** Schedule a local notification */
scheduleNotification: (notification: LocalNotification) => Promise<string>;
/** Cancel a scheduled notification */
cancelNotification: (notificationId: string) => Promise<void>;
}

function useHostPush(): UseHostPushReturn;

Return Value

PropertyTypeDescription
tokenstring | nullFCM/APNs push token
hasPermissionbooleanWhether notification permission is granted
badgeCountnumberCurrent app badge count
isLoadingbooleanLoading state
errorError | nullError if any operation failed
refresh() => Promise<void>Refresh push state
requestPermission() => Promise<boolean>Request notification permission
setBadgeCount(count: number) => Promise<void>Set badge count
clearBadge() => Promise<void>Clear badge
subscribeToTopic(topic: string) => Promise<void>Subscribe to FCM topic
unsubscribeFromTopic(topic: string) => Promise<void>Unsubscribe from topic
scheduleNotification(notification: LocalNotification) => Promise<string>Schedule local notification
cancelNotification(notificationId: string) => Promise<void>Cancel scheduled notification

Example

import { useHostPush } from '@54vie/miniapp-sdk';

function NotificationSettings() {
const {
token,
hasPermission,
badgeCount,
isLoading,
requestPermission,
subscribeToTopic,
scheduleNotification,
clearBadge,
} = useHostPush();

const handleEnableNotifications = async () => {
const granted = await requestPermission();
if (granted && token) {
// Send token to your server
await api.registerDevice(token);
// Subscribe to topics
await subscribeToTopic('promotions');
await subscribeToTopic('order_updates');
}
};

const scheduleReminder = async () => {
const notificationId = await scheduleNotification({
title: 'Reminder',
body: 'Your order is ready for pickup!',
fireDate: Date.now() + 3600000, // 1 hour from now
sound: 'default',
data: { orderId: '12345' },
});
console.log('Scheduled notification:', notificationId);
};

if (isLoading) return <ActivityIndicator />;

return (
<View>
<Text>Notifications: {hasPermission ? 'Enabled' : 'Disabled'}</Text>
<Text>Badge Count: {badgeCount}</Text>

{!hasPermission && (
<Button
title="Enable Notifications"
onPress={handleEnableNotifications}
/>
)}

<Button title="Schedule Reminder" onPress={scheduleReminder} />
<Button title="Clear Badge" onPress={clearBadge} />
</View>
);
}

Hook Dependencies

All hooks use the bridge communication layer to interact with the host app:

useHostAuth      -> bridge.send('auth.getAccessToken')
useHostDevice -> bridge.send('device.getInfo')
useHostStorage -> bridge.send('storage.get', 'storage.set', ...)
useHostAnalytics -> bridge.emit('analytics.track', 'analytics.screen')
useHostPush -> bridge.send('push.getToken', 'push.requestPermission', ...)

For more information on the bridge protocol, see the Bridge API documentation.