React Native - Moments Prefetch Integration Guide
Overview
This guide explains how to integrate the MomentScience Moments solution into your React Native application to present personalized offers during the checkout experience.
The guide covers two integration modes, both designed to preload and display offers in a WebView:
- SDK Prefetch Mode
- API Prefetch Mode
Both options deliver a high-performing native experience while maintaining a lightweight and flexible integration.
Integration Modes
SDK Prefetch Mode
The SDK automatically preloads and caches offers using a 0Γ0 WebView placed in advance of checkout. Offers are displayed instantly when the user reaches the checkout step.
- Easiest integration path
- No need to make manual API calls
API Prefetch Mode
Your app uses a native HTTPS request to fetch offers from the Moments API and passes the response into the SDK during checkout.
- Full control over when and how offers are requested
- Ability to customize the request payload (e.g., user ID, cart value)
In both modes, the offers are rendered inside a WebView on the checkout screen. Offers are preloaded ahead of time, so user experience remains responsive, even when no offers are available. If no offers are returned, your app can skip rendering the offer section.
To see a full implementation, check out the MomentScience React Native Demo on GitHub which includes examples for offer fetching, event handling, and WebView integration.
Requirements
To integrate the MomentScience SDK into your React Native app, ensure the following prerequisites are met:
- A valid MomentScience SDK ID, which you can obtain by following these steps.
- Environment:
- React: 18.0.0
- React-Native: 0.70.0
Integration Steps
Step 1: Add Dependencies
Install Dependencies
Install below packages into your react-native app:
react-native-webview
react-native-dotenv (optional)Add Internet Permission
To allow offer content to load, add the following permission in To allow offer content to load, add the following permission in android/app/src/main/AndroidManifest.xmlinside <manifest>but before <application>
<uses-permission android:name="android.permission.INTERNET" />This is required for the SDK to load offer content in both integration modes.
Step 2: Prefetch Offers (SDK or API)
You can prefetch offers using one of two modes:
- SDK Prefetch: Uses a hidden 0Γ0 WebView to preload offers.
- API Prefetch: Uses a native API call to fetch offers, which are then injected into the SDK display template.
In both modes, you can skip showing the checkout screen if no offers are found.
Option 1: SDK Prefetch
This method uses a hidden 0Γ0 WebView to preload the Moments SDK in the background. When available offers are detected, the SDK triggers an ads_found event in your app. This is the most lightweight integration method and is ideal when you want to minimize native code involvement.
- Set up the WebView: Place a hidden 0Γ0 WebView on any screen before checkout. Make sure to enable the following WebView settings:
- javaScriptEnabled = true
- domStorageEnabled = true
- originWhitelist = {[ββ]}*
- Register JavaScript Event Handler: The Web SDK communicates with your app through JavaScript events. You must handle these events in your app to react to SDK events. Implement onMessage handler to listen for SDK events.
const handleMessage = useCallback(message => {
try {
const data = JSON.parse(message.nativeEvent.data);
if (data.name === 'ads_found') {
setOffersCount(data.total || 0);
}
} catch (err) {
// handle error gracefully
}
}, []);- Load WebView with the prefetch HTML template: Use the existing prefetch template from prefetch.js. Inject your SDKID, SDK CDN URL, AdpxUser configuration dynamically, then load the resulting HTML into the WebView.
export const getWebSDKHtml = (sdkId, payload) => {
let html = processTemplate(prefetchTemplate, {
SDK_ID: sdkId,
CDN_URL: SDK_CONFIG.CDN_URL,
});
// Create AdpxUser script with payload
if (payload) {
const adpxUserScript = createAdpxUserScript(payload);
html = html.replace('window.AdpxUser = {};', adpxUserScript);
}
return html;
};
- Handle ads_foundEvent: Once the WebView receives the ads_found event, extract the offer count. If offer Count == 0, you can skip rendering the offer UI entirely.
To see working example of how to load prefetch html with injected configurations, refer webSDKUtils.js, prefetch.js, adpxUtils.js, HomeScreen.js in demo app.
Option 2: Prefetch with API
This method allows your app to prefetch offers directly from the Moments API and pass them into the Web SDK via script injection.
For complete details on Moments API, refer to the Moments API documentation.
- Send a POSTrequest to the Moments API:
POST https://api.adspostx.com/native/v4/offers.json- Build the Request Parameters: Include the following:
- api_key as a query parameter
- A user payload in the request body
- Custom User-Agent in the request headers
- Validate Optional Parameters (if used):
- loyaltyboost must be "0", "1", or "2"
- creative must be "0" or "1"
- Prepare and Send the Request: Use the following example code to construct and send the request:
// API_BASE_URL=https://api.adspostx.com/native/v4
export const fetchOffers = async ({
sdkId,
loyaltyBoost = '0',
creative = '0',
campaignId = null,
isDevelopment = false,
payload = {},
}) => {
if (!sdkId) {
throw new Error('SDK ID is required');
}
// Validate loyaltyBoost
if (!['0', '1', '2'].includes(loyaltyBoost)) {
throw new Error('Invalid loyaltyBoost value. Must be "0", "1", or "2"');
}
// Validate creative
if (!['0', '1'].includes(creative)) {
throw new Error('Invalid creative value. Must be "0" or "1"');
}
try {
// Create base query parameters
const queryParams = new URLSearchParams();
queryParams.append('api_key', sdkId);
queryParams.append('loyaltyboost', loyaltyBoost);
queryParams.append('creative', creative);
// Add campaignId if provided
if (campaignId !== null) {
queryParams.append('campaignId', campaignId);
}
// Get user agent from payload or generate it
const userAgent = payload.ua || generateUserAgent();
// Construct request options
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'User-Agent': userAgent,
},
body: JSON.stringify({
...(isDevelopment ? { dev: 1 } : {}),
...payload,
}),
};
const response = await fetch(
`${API_CONFIG.BASE_URL}/offers.json?${queryParams.toString()}`,
requestOptions,
);
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(
errorData.message ||
`API request failed with status ${response.status}`,
);
}
return await response.json();
} catch (error) {
throw new Error(`Failed to fetch offers: ${error.message}`);
}
};- Save the API Response Locally: Store the JSON response from the API to use it when initializing the SDK.
To see working implementation of API call refer api.js, helpers.js in the demo app.
Step 3: Show Offers Using Fullscreen WebView
After confirming that offers are available, display them on your checkout screen using a fullscreen WebView. Pass the necessary parameters depending on the prefetch method.
- Navigate to the Checkout Screen
const handleProceedToCheckout = useCallback(() => {
const params = {
sdkId,
apiResponse:
selectedPrefetchMethod === PrefetchMethod.API ? response : null, // only require for api prefetch
prefetchMethod: selectedPrefetchMethod, // not require, as you are going to use one of the approach.
offersCount: getOffersCount(), // optional, require only if you want to show no of offers in checkout screen
payload: currentPayload,
userAgent: generateUserAgent(),
};
navigation.navigate('Checkout', params);
}, [
navigation,
sdkId,
response,
selectedPrefetchMethod,
getOffersCount,
currentPayload,
]);- Load the Offer experience: Inside the CheckoutScreen, load the offer experience into the WebView using checkout.js. Follow these steps:
- Read html from checkout.js.
- Replace placeholders like %%SDK_ID%%, %%AUTOLOAD_CONFIG%%, %%CDN_URL%%, %%RESPONSE_HANDLING%% with actual values (from the payload or API response).
- Ensure JavaScript, DOM storage settings are enabled in the WebView.
- Load the final HTML into WebView.
- Choose Logic Based on Prefetch Mode: Use different logic depending on whether you're using:
- Prefetch with SDK: Cached offers are automatically shown by the SDK.
- Prefetch with API: You need to pass the saved apiResponse and inject it via JavaScript.
const htmlContent = useMemo(() => {
return getCheckoutHtml({
sdkId,
offersCount,
autoLoadConfig: getAutoLoadConfiguration(),
responseHandling: getResponseHandlingScript(),
adpxUserScript:
(),
});
}, [
sdkId,
offersCount,
getAutoLoadConfiguration,
getResponseHandlingScript,
getAdpxUserScript,
]);Checkout adpxUtils.js, useCheckout.jsv, CheckoutScreen.js in the demo app for working implementation.
Step 4: Open Clicks in an External Browser
To ensure that offer clickouts open in the deviceβs default browser (rather than inside the WebView), listen for SDK callback events and handle the URL externally.
Handle onNavigationStateChange callback to open any url in external browser.
const handleNavigationStateChange = navState => {
// If the URL is not about:blank or your domain URL, open in external browser
if (
navState.url &&
navState.url !== 'about:blank' &&
!navState.url.startsWith('https://exampledomain.com')
) {
Linking.openURL(navState.url).catch(err => {
console.error('Failed to open URL:', err);
});
return false; // Prevent WebView from loading the URL
}
return true;
};Checkout CheckoutScreen.js in the demo app for working implementation.
Conclusion
Congratulations! You've now completed the integration of the MomentScience SDK into your React Native app.
Whether you're using SDK Prefetch Mode or API Prefetch Mode, your app is now ready to deliver personalized offers directly within the user journey, enhancing monetization while maintaining full control over offer timing and display.
π’ If you're running into any issues while going through the integration process, feel free to contact us at [email protected]ο»Ώ