Getting Started
Copy a setup prompt with the install steps and the full markdown guide for this plugin.
Set up this Capacitor plugin in the project.
Use the package manager already used by the project.
Install these package(s): `@capgo/capacitor-live-activities`
Run the required Capacitor sync/update step after installation.
Read this markdown guide for the full setup steps: https://raw.githubusercontent.com/Cap-go/website/refs/heads/main/apps/docs/src/content/docs/docs/plugins/live-activities/getting-started.mdx
Use that guide for platform-specific steps, native file edits, permissions, config changes, imports, and usage setup.
If that guide references other docs pages, read them too.
Install
Section titled “Install”bun add @capgo/capacitor-live-activitiesbunx cap synciOS Setup
Section titled “iOS Setup”Installing and syncing the plugin does not create the native Live Activity UI. ActivityKit requires a Widget Extension that registers a Live Activity configuration before startActivity can display anything.
Requirements
Section titled “Requirements”- Use iOS 16.1 or later for both the app target and Widget Extension target.
- Test on an iOS device or a compatible simulator. The Dynamic Island only appears on supported device models; other devices use the Lock Screen presentation.
- Keep the combined static and dynamic ActivityKit data below Apple’s 4 KB limit.
1. Create a Widget Extension
Section titled “1. Create a Widget Extension”Open the native iOS project:
bunx cap open iosThen:
- Select File > New > Target.
- Add a Widget Extension.
- Enable Include Live Activity.
- Disable Include Configuration Intent unless the app also needs a configurable widget.
- Ensure the generated extension is embedded in the main app target.
The Widget Extension must contain an ActivityConfiguration and register it in its WidgetBundle. It must provide every required Live Activity presentation:
- Lock Screen
- Dynamic Island expanded
- Dynamic Island compact leading and trailing
- Dynamic Island minimal
Adding the target alone is not sufficient. The native app or plugin must call ActivityKit’s request, update, and end APIs. The extension must contain SwiftUI code that can decode and render the same ActivityAttributes and content state used by those calls. Include shared ActivityKit models in both the main app and Widget Extension targets. The Xcode-generated Live Activity template does not automatically render the JSON layouts passed to this plugin; the extension also needs a compatible native layout renderer.
2. Enable Live Activities
Section titled “2. Enable Live Activities”Add the following key to the main app target’s Info.plist:
<key>NSSupportsLiveActivities</key><true/>If the project generates its Info.plist, add Supports Live Activities with a Boolean value of YES under the main app target’s custom iOS target properties instead.
3. Configure the App Group for Shared Images
Section titled “3. Configure the App Group for Shared Images”An App Group is only required when using saveImage, removeImage, listImages, or cleanupImages. The plugin derives the App Group identifier from the main app bundle identifier using this exact format:
group.<MAIN_APP_BUNDLE_ID>.liveactivitiesFor example, an app with bundle identifier com.example.delivery must use:
group.com.example.delivery.liveactivitiesIn Xcode, add the App Groups capability to both the main app target and the Widget Extension target, then enable the same identifier on both targets.
Live Activity extensions cannot access the network. Download remote images in the main app and save them to the shared App Group before referencing them from a Live Activity. For bundled images, also enable the Widget Extension in the asset’s target membership.
4. Configure Deep Links
Section titled “4. Configure Deep Links”When using behavior.widgetUrl or a timer sequence tapUrl, register the matching URL scheme or Universal Link in the main app. For a custom scheme such as myapp://order/12345, add the scheme under the main app target’s Info > URL Types settings.
5. Optional: Enable Server-Driven Updates
Section titled “5. Optional: Enable Server-Driven Updates”Push Notifications are not required for local updates initiated by the app. To start, update, or end Live Activities from a server:
- Add the Push Notifications capability to the main app target.
- Obtain ActivityKit push tokens and send them to the server.
- Send ActivityKit notifications through APNs using the
liveactivitypush type. - Add
NSSupportsLiveActivitiesFrequentUpdatesto the main appInfo.plistonly when the use case requires frequent push updates.
ActivityKit push tokens are separate from standard user-notification device tokens. Enabling the Push Notifications capability alone is not sufficient; server-driven updates require native token handling and an APNs backend.
Native Setup Checklist
Section titled “Native Setup Checklist”Before calling startActivity, verify that:
NSSupportsLiveActivitiesis enabled on the main app target.- The Widget Extension is embedded and registers an
ActivityConfiguration. - The native ActivityKit implementation and Widget Extension use the same
ActivityAttributestype. - The app and Widget Extension deployment targets are iOS 16.1 or later.
- Live Activities are enabled for the app in iOS Settings.
- The matching App Group is enabled on both targets when using shared images.
- Any custom URL scheme used by
widgetUrlortapUrlis registered.
Import
Section titled “Import”import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';API Overview
Section titled “API Overview”areActivitiesSupported
Section titled “areActivitiesSupported”Check if Live Activities are supported on this device. Requires iOS 16.1+ and device support.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { supported, reason } = await CapgoLiveActivities.areActivitiesSupported();if (supported) { console.log('Live Activities are supported!');} else { console.log('Not supported:', reason);}startActivity
Section titled “startActivity”Start a new Live Activity with the specified layout and data.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { activityId } = await CapgoLiveActivities.startActivity({ layout: { type: 'container', direction: 'horizontal', children: [ { type: 'text', content: 'Order #{{orderNumber}}', fontSize: 16, fontWeight: 'bold' }, { type: 'text', content: '{{status}}', fontSize: 14, color: '#666666' } ] }, dynamicIslandLayout: { expanded: { leading: { type: 'image', source: 'sfSymbol', value: 'box.truck' }, trailing: { type: 'text', content: '{{eta}}' }, center: { type: 'text', content: '{{status}}' }, bottom: { type: 'progress', value: 'progress' } }, compactLeading: { type: 'image', source: 'sfSymbol', value: 'box.truck' }, compactTrailing: { type: 'text', content: '{{eta}}' }, minimal: { type: 'image', source: 'sfSymbol', value: 'box.truck' } }, data: { orderNumber: '12345', status: 'On the way', eta: '10 min', progress: 0.6 }});console.log('Started activity:', activityId);updateActivity
Section titled “updateActivity”Update an existing Live Activity with new data.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.updateActivity({ activityId: 'abc123', data: { status: 'Arrived!', eta: 'Now', progress: 1.0 }, alertConfiguration: { title: 'Delivery Update', body: 'Your order has arrived!' }});endActivity
Section titled “endActivity”End a Live Activity.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.endActivity({ activityId: 'abc123', data: { status: 'Delivered' }, dismissalPolicy: 'after', dismissAfter: Date.now() + 3600000 // 1 hour from now});getAllActivities
Section titled “getAllActivities”Get all currently active Live Activities.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { activities } = await CapgoLiveActivities.getAllActivities();activities.forEach(activity => { console.log(`Activity ${activity.activityId}: ${activity.state}`);});saveImage
Section titled “saveImage”Save an image to the shared App Group container for use in Live Activities. Images must be saved to the shared container to be accessible from the widget extension.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { success, imageName } = await CapgoLiveActivities.saveImage({ imageData: 'base64EncodedImageData...', name: 'product-image', compressionQuality: 0.8});// Use in layout with: { type: 'image', source: 'saved', value: imageName }removeImage
Section titled “removeImage”Remove a saved image from the shared container.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { success } = await CapgoLiveActivities.removeImage({ name: 'product-image' });listImages
Section titled “listImages”List all saved images in the shared container.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { images } = await CapgoLiveActivities.listImages();console.log('Saved images:', images);cleanupImages
Section titled “cleanupImages”Remove all saved images from the shared container.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.cleanupImages();startTimerSequence
Section titled “startTimerSequence”Start a timer sequence for workouts/sports. On iOS: Shows in Live Activity and Dynamic Island On Android: Shows as a foreground notification with timer
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { sequenceId } = await CapgoLiveActivities.startTimerSequence({ title: 'HIIT Workout', steps: [ { duration: 30, title: 'Jumping Jacks', subtitle: 'Warm up', color: '#FF6B00', icon: 'figure.jumprope' }, { duration: 10, title: 'Rest', color: '#00C853', icon: 'pause.circle' }, { duration: 45, title: 'Burpees', subtitle: 'High intensity', color: '#FF0000', icon: 'flame.fill' }, { duration: 15, title: 'Rest', color: '#00C853', icon: 'pause.circle' }, { duration: 45, title: 'Mountain Climbers', color: '#FF0000', icon: 'figure.run' }, { duration: 15, title: 'Rest', color: '#00C853', icon: 'pause.circle' }, ], loop: true, loopCount: 3, soundEnabled: true, vibrateEnabled: true, countdownBeeps: true, tapUrl: 'myapp://workout/hiit'});pauseTimerSequence
Section titled “pauseTimerSequence”Pause the timer sequence.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.pauseTimerSequence({ sequenceId: 'abc123' });resumeTimerSequence
Section titled “resumeTimerSequence”Resume a paused timer sequence.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.resumeTimerSequence({ sequenceId: 'abc123' });stopTimerSequence
Section titled “stopTimerSequence”Stop and dismiss the timer sequence.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.stopTimerSequence({ sequenceId: 'abc123' });skipTimerStep
Section titled “skipTimerStep”Skip to the next step in the sequence.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.skipTimerStep({ sequenceId: 'abc123' });previousTimerStep
Section titled “previousTimerStep”Go back to the previous step in the sequence.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.previousTimerStep({ sequenceId: 'abc123' });getTimerState
Section titled “getTimerState”Get the current state of a timer sequence.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const state = await CapgoLiveActivities.getTimerState({ sequenceId: 'abc123' });console.log(`Step ${state.currentStepIndex + 1}/${state.totalSteps}: ${state.currentStep.title}`);console.log(`Time remaining: ${state.remainingSeconds}s`);Type Reference
Section titled “Type Reference”AreActivitiesSupportedResult
Section titled “AreActivitiesSupportedResult”Result of checking if activities are supported.
export interface AreActivitiesSupportedResult { /** Whether Live Activities are supported on this device */ supported: boolean; /** Reason if not supported */ reason?: string;}StartActivityOptions
Section titled “StartActivityOptions”Options for starting a Live Activity.
export interface StartActivityOptions { /** Main activity layout (lock screen widget) */ layout: ActivityLayout; /** Dynamic Island layout configuration */ dynamicIslandLayout: DynamicIslandLayout; /** Activity behavior settings */ behavior?: LiveActivitiesBehavior; /** Dynamic data for the activity */ data: Record<string, unknown>; /** Stale date timestamp (activity becomes stale after this) */ staleDate?: number; /** Relevance score for activity ordering (0-100) */ relevanceScore?: number;}StartActivityResult
Section titled “StartActivityResult”Result of starting an activity.
export interface StartActivityResult { /** Unique activity identifier */ activityId: string;}UpdateActivityOptions
Section titled “UpdateActivityOptions”Options for updating a Live Activity.
export interface UpdateActivityOptions { /** Activity ID to update */ activityId: string; /** Updated data */ data: Record<string, unknown>; /** Optional alert to show with update */ alertConfiguration?: ActivityAlertConfiguration; /** Updated stale date */ staleDate?: number; /** Updated relevance score */ relevanceScore?: number;}EndActivityOptions
Section titled “EndActivityOptions”Options for ending a Live Activity.
export interface EndActivityOptions { /** Activity ID to end */ activityId: string; /** Final data to display */ data?: Record<string, unknown>; /** Dismissal policy */ dismissalPolicy?: 'immediate' | 'default' | 'after'; /** Dismiss after timestamp (when dismissalPolicy is 'after') */ dismissAfter?: number;}GetAllActivitiesResult
Section titled “GetAllActivitiesResult”Result of getAllActivities.
export interface GetAllActivitiesResult { /** List of activities */ activities: ActivityInfo[];}SaveImageOptions
Section titled “SaveImageOptions”Options for saving an image.
export interface SaveImageOptions { /** Base64 encoded image data */ imageData: string; /** Name to save the image as */ name: string; /** JPEG compression quality (0-1, default 0.8) */ compressionQuality?: number;}SaveImageResult
Section titled “SaveImageResult”Result of saving an image.
export interface SaveImageResult { /** Whether the save was successful */ success: boolean; /** Saved image name */ imageName: string;}RemoveImageOptions
Section titled “RemoveImageOptions”Options for removing an image.
export interface RemoveImageOptions { /** Name of the image to remove */ name: string;}RemoveImageResult
Section titled “RemoveImageResult”Result of removing an image.
export interface RemoveImageResult { /** Whether the removal was successful */ success: boolean;}ListImagesResult
Section titled “ListImagesResult”Result of listing images.
export interface ListImagesResult { /** List of saved image names */ images: string[];}TimerSequenceOptions
Section titled “TimerSequenceOptions”Options for starting a timer sequence.
export interface TimerSequenceOptions { /** Array of steps in the sequence */ steps: TimerStep[]; /** Overall title for the sequence (e.g., "HIIT Workout", "Tabata") */ title?: string; /** Whether to loop the sequence when complete */ loop?: boolean; /** Number of times to loop (if loop is true, 0 means infinite) */ loopCount?: number; /** Play sound on step change (default: true) */ soundEnabled?: boolean; /** Vibrate on step change (default: true) */ vibrateEnabled?: boolean; /** Play countdown beeps in last 3 seconds (default: true) */ countdownBeeps?: boolean; /** Deep link URL when tapping the notification/activity */ tapUrl?: string; /** Keep screen on during timer (Android only, default: false) */ keepScreenOn?: boolean;}Source Of Truth
Section titled “Source Of Truth”This page is generated from the plugin’s src/definitions.ts. Re-run the sync when the public API changes upstream.
Keep going from Getting Started
Section titled “Keep going from Getting Started”If you are using Getting Started to plan dashboard and API operations, connect it with Using @capgo/capacitor-live-activities for the native capability in Using @capgo/capacitor-live-activities, API Overview for the implementation detail in API Overview, Introduction for the implementation detail in Introduction, API Keys for the implementation detail in API Keys, and Devices for the implementation detail in Devices.