📱 Native Widgets
ShipNative includes preconfigured native widgets for both iOS and Android platforms, with seamless Supabase integration for real-time data display.Overview
Widgets allow users to view key information from your app directly on their home screen without opening the app. ShipNative provides:- iOS Widgets - Built with SwiftUI, supporting all widget sizes
- Android Widgets - Built with Kotlin, supporting all widget sizes
- Supabase Integration - Automatic data fetching with authentication
- Easy Styling - Theme-aware widgets that match your app design
- Feature Flag - Easily enable/disable widgets via configuration
Quick Start
1. Enable Widgets
Widgets are disabled by default. To enable them, add to your.env file:
2. Install Dependencies
The widget package is already included inpackage.json. If you need to reinstall:
3. Run Prebuild
Widgets require native code, so you need to run prebuild:4. Build and Run
Widget Structure
Widgets are located inapp/widgets/:
Using Widgets in Your App
Fetching Widget Data
Use theuseWidgetData hook to fetch data for widgets:
Widget Service
The widget service handles secure data fetching with caching:Supabase Integration
Sharing Session Tokens
Widgets need access to Supabase session tokens to fetch authenticated data. The app automatically shares tokens via:- iOS: App Groups (UserDefaults)
- Android: SharedPreferences
Setting Up App Groups (iOS)
- In Xcode, select your app target
- Go to “Signing & Capabilities”
- Add “App Groups” capability
- Create a new group:
group.com.yourcompany.yourapp - Update
ExampleWidget.swiftwith your App Group identifier
Data Fetching in Widgets
Widgets fetch data directly from Supabase using the REST API: iOS (Swift):Styling Widgets
iOS Widget Styling
Widgets use SwiftUI with theme colors:Android Widget Styling
Widgets use XML layouts with theme colors:example_widget.xml to match your app theme.
Security Best Practices
1. Row Level Security (RLS)
Enable RLS policies in Supabase for widget-accessible tables:2. Token Management
- Store session tokens securely in App Groups/SharedPreferences
- Tokens are automatically refreshed by the main app
- Widgets use read-only access to tokens
3. Data Validation
Always validate data before displaying in widgets:4. Rate Limiting
Widget updates are rate-limited to prevent excessive API calls:- Minimum 5 minutes between updates
- 15-minute cache duration
- Maximum 10 cached items
Creating Custom Widgets
iOS Widget
- Create a new Swift file in
app/widgets/ios/ - Implement
TimelineProviderprotocol - Create SwiftUI view for widget content
- Register widget in
ExampleWidget.swift
Android Widget
- Create a new Kotlin file in
app/widgets/android/ - Extend
AppWidgetProvider - Create XML layout in
res/layout/ - Register widget in
widget_info.xml
Troubleshooting
Widget Not Showing
- Check feature flag: Ensure
EXPO_PUBLIC_ENABLE_WIDGETS=true - Run prebuild: Widgets require native code generation
- Check logs: Look for widget-related errors in Xcode/Android Studio
Data Not Loading
- Check Supabase config: Verify URL and key are set
- Check session token: Ensure user is authenticated
- Check RLS policies: Widgets need appropriate permissions
- Check network: Widgets need internet access
Build Errors
- iOS: Check App Group identifier matches in app and widget
- Android: Check package name matches in widget files
- Missing files: Ensure all widget files are in correct locations
Examples
Displaying User Profile
Displaying Recent Posts
API Reference
useWidgetData Hook
table: string- Supabase table nameselect?: string- Columns to select (default: ”*”)filters?: Record<string, any>- Filter conditionslimit?: number- Maximum rows (default: 10)orderBy?: { column: string; ascending?: boolean }- Sort orderrequireAuth?: boolean- Require authentication (default: false)cacheKey?: string- Custom cache keyrefreshInterval?: number- Auto-refresh interval in msenabled?: boolean- Enable/disable hook (default: true)
data: T | null- Fetched dataloading: boolean- Loading stateerror: Error | null- Error if anyrefetch: () => Promise<void>- Manual refreshclearCache: () => void- Clear cacheconfig: WidgetConfig- Widget configuration
Widget Service
Next Steps
- Read Security Guide for security considerations
- Check Widget Examples for implementation patterns
- Review Troubleshooting for common issues