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
| Property | Type | Description |
|---|---|---|
user | User | null | Current user object or null if not authenticated |
isAuthenticated | boolean | Whether 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
| Property | Type | Description |
|---|---|---|
info | DeviceInfo | null | Complete device information |
battery | BatteryInfo | null | Battery status information |
isLoading | boolean | Loading state |
error | Error | null | Error 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
| Method | Type | Description |
|---|---|---|
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>
);
}
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
| Method | Type | Description |
|---|---|---|
trackEvent | (name: string, properties?: Record<string, unknown>) => void | Track custom event |
trackScreen | (screenName: string) => void | Track 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>
);
}
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
| Property | Type | Description |
|---|---|---|
token | string | null | FCM/APNs push token |
hasPermission | boolean | Whether notification permission is granted |
badgeCount | number | Current app badge count |
isLoading | boolean | Loading state |
error | Error | null | Error 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.