Preroll Ads
Preroll ads are video ads that play before your content. The SDK manages playback automatically using Google IMA — the ad auto-plays with no user-visible controls. Users can skip the ad when the VAST creative allows it.
After the ad completes, is skipped, or fails, your content can start playing automatically. No additional handling is needed.
Each ad format uses a Zone ID to identify the ad placement. Zone IDs are configured in the Empower dashboard.
Note: All ad listeners are optional. The SDK handles ad loading, playback, and fallback automatically. Use listeners only if you need to track ad states for analytics or UI updates.
Platform Differences
Preroll ads use different native player components per platform:
| Platform | Player Component | Container |
|---|---|---|
| Android | PlayerView (Media3/ExoPlayer) | androidx.media3.ui.PlayerView |
| iOS | IMA SDK | UIView container |
Important (iOS): The IMA SDK requires
rootViewControllerto be set for proper ad presentation. The React Native bridge sets this automatically duringinit()viaEMASettings.shared.rootViewController. If you encounter issues with preroll ads not displaying on iOS, ensure SDK initialization completes before loading preroll ads.
Loading a Preroll Ad
Using loadPrerollAd
import {loadPrerollAd,addEventListener,EmpowerAdsEvents,AdStatus,} from '@empower-nokta/react-native-mobile-ads';const ZONE_ID = { android: 'ANDROID_PREROLL_ZONE_ID', ios: 'IOS_PREROLL_ZONE_ID' };// Load preroll ad with a content video URLloadPrerollAd({zoneId: ZONE_ID,contentUrl: 'https://example.com/your-content-video.mp4',muted: false, // Optional: mute ad audio});
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
zoneId | string \| { android?: string, ios?: string } | Yes | — | The zone ID for the preroll placement |
contentUrl | string | Yes | — | URL of the content video that plays after the ad |
muted | boolean | No | false | Whether to mute audio during ad playback |
Using the EmpowerPrerollView Component
For inline video ad placement, use the EmpowerPrerollView component:
import { EmpowerPrerollView } from '@empower-nokta/react-native-mobile-ads';function VideoScreen() {return (<EmpowerPrerollViewzoneId="YOUR_PREROLL_ZONE_ID"contentUrl="https://example.com/your-content-video.mp4"muted={false}onPrerollStatusChanged={(event) => {console.log('Preroll status:', event.nativeEvent.status);}}onPrerollAdEvent={(event) => {console.log('IMA event:', event.nativeEvent.type);}}style={{ width: '100%', aspectRatio: 16 / 9 }}/>);}
Props
| Prop | Type | Required | Description |
|---|---|---|---|
zoneId | string \| { android?: string, ios?: string } | Yes | Zone ID for the preroll placement |
contentUrl | string | Yes | URL of the content video |
muted | boolean | No | Mute ad audio (default: false) |
onPrerollStatusChanged | (event) => void | No | Called when preroll ad status changes |
onPrerollAdEvent | (event) => void | No | Called for IMA ad events (quartile progress, etc.) |
style | ViewStyle | No | Container style. Recommended: { width: '100%', aspectRatio: 16/9 } |
Listening to Preroll Events (Optional)
Status Changes
import { addEventListener, EmpowerAdsEvents, AdStatus } from '@empower-nokta/react-native-mobile-ads';const unsubStatus = addEventListener(EmpowerAdsEvents.PREROLL_STATUS,(event) => {switch (event.status) {case AdStatus.READY:// Ad is loaded and about to playbreak;case AdStatus.ACTIVE:// Ad is playingbreak;case AdStatus.COMPLETE_PLAYING:// Ad finished — content video is now playingbreak;case AdStatus.FAILED:// Ad failed — content video plays automaticallybreak;case AdStatus.PAUSED:// Ad playback pausedbreak;}});// Clean upunsubStatus();
IMA Ad Events
Track granular ad playback progress:
const unsubAd = addEventListener(EmpowerAdsEvents.PREROLL_AD,(event) => {switch (event.type) {case 'STARTED':// Ad playback startedbreak;case 'FIRST_QUARTILE':// 25% of the ad has playedbreak;case 'MIDPOINT':// 50% of the ad has playedbreak;case 'THIRD_QUARTILE':// 75% of the ad has playedbreak;case 'COMPLETE':// Ad playback finishedbreak;case 'SKIPPED':// User skipped the adbreak;case 'CLICKED':// User clicked the adbreak;}});// Clean upunsubAd();
Lifecycle Management
The SDK automatically manages the ad lifecycle based on the component's visibility. For special cases like scrolling the video player off-screen in a FlatList, use the control functions:
import { pausePreroll, resumePreroll, destroyPreroll } from '@empower-nokta/react-native-mobile-ads';const ZONE_ID = 'YOUR_PREROLL_ZONE_ID';// Pause playback (e.g., view scrolled off-screen)pausePreroll(ZONE_ID);// Resume playback (e.g., view scrolled back)resumePreroll(ZONE_ID);// Release all resources when donedestroyPreroll(ZONE_ID);
| Method | Description |
|---|---|
pausePreroll(zoneId) | Pauses ad or content playback |
resumePreroll(zoneId) | Resumes playback |
destroyPreroll(zoneId) | Releases player resources |
Tip: Call
destroyPrerollwhen the screen unmounts to free native resources.
Complete Example
import React, { useEffect } from 'react';import { View, Text, StyleSheet } from 'react-native';import {EmpowerPrerollView,addEventListener,EmpowerAdsEvents,destroyPreroll,} from '@empower-nokta/react-native-mobile-ads';const ZONE_ID = { android: 'ANDROID_PREROLL_ZONE_ID', ios: 'IOS_PREROLL_ZONE_ID' };export default function VideoScreen() {useEffect(() => {const unsubStatus = addEventListener(EmpowerAdsEvents.PREROLL_STATUS,(event) => {console.log('Preroll status:', event.status);});const unsubAd = addEventListener(EmpowerAdsEvents.PREROLL_AD,(event) => {console.log('IMA event:', event.type);});return () => {unsubStatus();unsubAd();destroyPreroll(ZONE_ID);};}, []);return (<View style={styles.container}><EmpowerPrerollViewzoneId={ZONE_ID}contentUrl="https://example.com/content-video.mp4"style={styles.player}/><Text style={styles.title}>Video Title</Text><Text style={styles.description}>Video description goes here...</Text></View>);}const styles = StyleSheet.create({container: { flex: 1, backgroundColor: '#000' },player: { width: '100%', aspectRatio: 16 / 9 },title: { color: '#fff', fontSize: 18, fontWeight: 'bold', padding: 16 },description: { color: '#ccc', fontSize: 14, paddingHorizontal: 16 },});
Best Practices
- Set explicit aspect ratio — Use
aspectRatio: 16/9on the container for standard video proportions - Mute when appropriate — Set
muted={true}if the video auto-plays in a feed or silent context - Destroy on unmount — Always call
destroyPrerollin the cleanup function ofuseEffectto release native player resources - Frequency capping — The SDK respects server-configured session frequency caps
- Content URL required — Always provide a valid
contentUrl. The ad plays first, then transitions to your content video automatically
iOS: rootViewController
The IMA SDK on iOS requires a rootViewController reference for proper ad presentation. The bridge sets this automatically during SDK initialization:
// Set automatically inside init()EMASettings.shared.rootViewController = rootViewController
If preroll ads fail to display on iOS, verify that:
- SDK initialization (
init()) has completed before loading preroll ads - The app has a visible root view controller at the time of initialization
EMASettings.shared.rootViewControlleris set — the bridge does this automatically, but if you override initialization, ensure it's included
Ad Status Reference
| Status | Description |
|---|---|
READY | Ad is loaded and about to play |
ACTIVE | Ad is playing |
COMPLETE_PLAYING | Ad finished playing, content video is now playing |
SKIPPED | User skipped the ad, content video is now playing |
FAILED | Ad failed, content video plays automatically |
PAUSED | Ad playback paused |
Troubleshooting
Preroll Not Playing on iOS
- Check rootViewController is set:
// Enable debug logs to verifysetLogLevel('all');
Ensure SDK is initialized before loading preroll
Check zone ID is correct and active in the Empower dashboard
Preroll Not Playing on Android
Ensure Media3 (ExoPlayer) dependency is available — the SDK includes it transitively, but verify no version conflicts exist
Check the content URL is accessible — the SDK needs a valid video URL to transition to after the ad
Video Playback Issues
- Black screen: Verify container dimensions are set correctly (non-zero width and height)
- Audio issues: Check the
mutedprop and device volume settings - Memory leaks: Always call
destroyPrerollwhen navigating away from the video screen