Developing Widgets
Voltra provides APIs that make building and testing Home Screen widgets easier during development.
VoltraWidgetPreview component
Section titled “VoltraWidgetPreview component”VoltraWidgetPreview is a React Native component for testing and developing Voltra widget content. It renders Voltra JSX components at the exact dimensions of specific iOS widget families. This is useful for:
- Testing component layouts before deploying to widgets
- Previewing how your widget will look across different sizes
- Developing and iterating on widget content within your React Native app
import { ScrollView, View } from 'react-native'import { Voltra } from '@use-voltra/ios'import { VoltraWidgetPreview } from '@use-voltra/ios-client'
function MyWidgetContent() { return ( <Voltra.VStack style={{ padding: 16, backgroundColor: '#101828' }}> <Voltra.Text style={{ color: '#F8FAFC', fontSize: 18, fontWeight: '600' }}>Weather Widget</Voltra.Text> <Voltra.Text style={{ color: '#94A3B8', fontSize: 12, marginTop: 8 }}>Sunny, 72°F</Voltra.Text> </Voltra.VStack> )}
// Preview different widget sizes in your React Native screenfunction WidgetTestingScreen() { return ( <ScrollView style={{ flex: 1 }}> <View style={{ padding: 16, gap: 20 }}> <VoltraWidgetPreview family="systemSmall"> <MyWidgetContent /> </VoltraWidgetPreview>
<VoltraWidgetPreview family="systemMedium"> <MyWidgetContent /> </VoltraWidgetPreview>
<VoltraWidgetPreview family="systemLarge"> <MyWidgetContent /> </VoltraWidgetPreview> </View> </ScrollView> )}Props:
family: Widget family size to preview (systemSmall, systemMedium, systemLarge, etc.)style: Additional React Native styles to applyid: Unique identifier for the view (used for event filtering)onInteraction: Callback for user interactions with buttons/toggles
updateWidget API
Section titled “updateWidget API”The updateWidget function allows you to update home screen widget content with new data.
import { Voltra } from '@use-voltra/ios'import { updateWidget } from '@use-voltra/ios-client'
await updateWidget('weather', { systemSmall: <Voltra.Text>72°F</Voltra.Text>, systemMedium: ( <Voltra.HStack> <Voltra.Text>72°F</Voltra.Text> <Voltra.VStack> <Voltra.Text>Sunny</Voltra.Text> <Voltra.Text>High: 78° Low: 65°</Voltra.Text> </Voltra.VStack> </Voltra.HStack> ), systemLarge: ( <Voltra.VStack> <Voltra.Text style={{ fontSize: 24 }}>Weather</Voltra.Text> <Voltra.Text>72°F - Sunny</Voltra.Text> <Voltra.Text>High: 78° Low: 65°</Voltra.Text> </Voltra.VStack> ),}, { deepLinkUrl: 'myapp://weather' })Parameters:
widgetId: The widget identifier (as defined in your config plugin)variants: An object mapping widget families to specific contentoptions.deepLinkUrl: URL to open when the widget is tapped
scheduleWidget API
Section titled “scheduleWidget API”For widgets that need to change throughout the day, scheduleWidget lets you batch multiple updates in advance. iOS will automatically display each entry at its scheduled time—even when your app isn’t running.
import { Voltra } from '@use-voltra/ios'import { scheduleWidget } from '@use-voltra/ios-client'
// Schedule weather updates throughout the dayawait scheduleWidget('weather', [ { date: new Date('2026-01-16T09:00:00'), variants: { systemSmall: <Voltra.Text>Morning: 65°F ☀️</Voltra.Text>, systemMedium: <Voltra.Text>Good morning! 65°F and sunny</Voltra.Text> } }, { date: new Date('2026-01-16T15:00:00'), variants: { systemSmall: <Voltra.Text>Afternoon: 72°F ☀️</Voltra.Text>, systemMedium: <Voltra.Text>Afternoon: 72°F and sunny</Voltra.Text> } }, { date: new Date('2026-01-16T21:00:00'), variants: { systemSmall: <Voltra.Text>Evening: 68°F 🌙</Voltra.Text>, systemMedium: <Voltra.Text>Good evening! 68°F and clear</Voltra.Text> } }])Parameters:
widgetId: The widget identifier (as defined in your config plugin)entries: Array of timeline entries, each containing:date: When this content should be displayedvariants: Widget content for different size familiesdeepLinkUrl(optional): URL to open when tapping this specific entry
With deep links per entry:
await scheduleWidget('news', [ { date: new Date('2026-01-16T08:00:00'), variants: { systemSmall: <Voltra.Text>Morning Headlines</Voltra.Text> }, deepLinkUrl: '/news/morning' }, { date: new Date('2026-01-16T20:00:00'), variants: { systemSmall: <Voltra.Text>Evening Edition</Voltra.Text> }, deepLinkUrl: '/news/evening' }])Best practices:
- Schedule entries at realistic intervals (15+ minutes apart)
- Don’t schedule hundreds of entries—iOS has a daily refresh budget
- Use
updateWidgetfor immediate one-time updates - Use
scheduleWidgetfor predictable, recurring content changes
Widget configuration via Expo plugin
Section titled “Widget configuration via Expo plugin”Widgets are configured through the Voltra Expo config plugin. Add the widget configuration to your app.json or app.config.js:
{ "expo": { "plugins": [ [ "@use-voltra/ios-client", { "widgets": [ { "id": "weather", "displayName": "Weather Widget", "description": "Current weather conditions", "supportedFamilies": ["systemSmall", "systemMedium", "systemLarge"] } ] } ] ] }}Widget Configuration Properties:
id: Unique identifier for the widget (alphanumeric with underscores only)displayName: Name shown in the widget gallerydescription: Description shown in the widget gallerysupportedFamilies: Array of supported widget sizes (defaults to systemSmall, systemMedium, systemLarge)
Fallback logic for variants
Section titled “Fallback logic for variants”When a widget size doesn’t have specific content defined, Voltra automatically falls back to other available variants in this order:
systemMedium(preferred fallback for home screen widgets)systemSmallsystemLargesystemExtraLargeaccessoryRectangularaccessoryCircularaccessoryInline
This ensures your widget always displays content even when a specific size variant isn’t provided. For example, if you only define systemSmall and systemLarge, a systemMedium widget will use the systemSmall content.
// Only defining systemSmall and systemLargeawait updateWidget('minimal', { systemSmall: <Voltra.Text>72°F</Voltra.Text>, systemLarge: <Voltra.Text>Weather: 72°F - Sunny</Voltra.Text>,})
// systemMedium will automatically use systemSmall content as fallbackAdditional widget APIs
Section titled “Additional widget APIs”getActiveWidgets
Section titled “getActiveWidgets”Detect which widgets are currently installed on the user’s home screen:
import { getActiveWidgets } from '@use-voltra/ios-client'
const widgets = await getActiveWidgets()// [{ name: 'weather', family: 'systemSmall', kind: '...' }]See Querying Active Widgets for more details.
reloadWidgets
Section titled “reloadWidgets”Force widget timelines to refresh their content after updating shared resources like preloaded images:
import { reloadWidgets } from '@use-voltra/ios-client'
// Reload specific widgetsawait reloadWidgets(['weather', 'calendar'])
// Reload all widgetsawait reloadWidgets()clearWidget / clearAllWidgets
Section titled “clearWidget / clearAllWidgets”Remove stored widget data, causing widgets to show their placeholder state:
import { clearWidget, clearAllWidgets } from '@use-voltra/ios-client'
// Clear specific widgetawait clearWidget('weather')
// Clear all widgetsawait clearAllWidgets()