✨ Best Practices
Follow these recommendations to ensure optimal ad performance and user experience.
Ad Implementation
1. Always Check if an Ad is Ready
Before showing an ad, always check if it's ready to be displayed:
if (ad.isReady()) {
ad.show();
} else {
console.log("Ad not ready yet");
// Show loading indicator or alternative content
}
2. Use Event Listeners for Better Control
Event listeners provide better control over the ad lifecycle:
// Listen for when the ad is ready
ad.addEventListener("onReady", () => {
// Enable ad button or update UI
showAdButton.disabled = false;
});
// Handle errors
ad.addEventListener("onError", () => {
// Update UI to show error state
errorMessage.style.display = "block";
});
// Handle ad closure
ad.addEventListener("onSkip", () => {
// Resume app flow
resumeGame();
});
3. Clean up Event Listeners
To prevent memory leaks, clean up event listeners when they're no longer needed:
const onReadyHandler = () => {
console.log("Ad is ready");
};
// Add the event listener
ad.addEventListener("onReady", onReadyHandler);
// When you're done with it (e.g., component unmount in React)
ad.removeEventListener("onReady", onReadyHandler);
4. Provide Fallback Content
Always have a plan for when ads are not available:
ad.addEventListener("adNotFound", () => {
// Hide ad-related UI
adButton.style.display = "none";
// Show alternative content
alternativeContent.style.display = "block";
});
User Experience
1. Place Ads at Natural Break Points
For interstitial ads, place them at natural transition points in your application:
- Between levels in a game
- After completing an action
- When navigating between different sections
2. Respect Frequency Caps
Avoid showing too many ads in a short period:
// Example: Simple time-based frequency cap for interstitial ads
const MIN_TIME_BETWEEN_ADS = 120000; // 2 minutes in milliseconds
let lastAdShownTime = 0;
function showInterstitialAd() {
const currentTime = Date.now();
if (currentTime - lastAdShownTime >= MIN_TIME_BETWEEN_ADS) {
if (interstitialAd.isReady()) {
interstitialAd.show();
lastAdShownTime = currentTime;
}
} else {
console.log("Ad frequency cap not yet reached");
}
}
3. Make Rewarded Ads Truly Optional
For rewarded ads, always:
- Clearly communicate the reward
- Make viewing the ad optional
- Deliver the promised reward consistently
rewardedAd.show({
onClosed: () => {
// Verify the ad was completed and reward the user
giveUserReward();
// Update UI to show reward received
updateRewardUI();
}
});
4. Loading State Indicators
Provide clear loading indicators when ads are being loaded:
// Initially disable the button and show loading state
adButton.disabled = true;
adButton.textContent = "Loading Ad...";
// When ad is ready, update UI
ad.addEventListener("onReady", () => {
adButton.disabled = false;
adButton.textContent = "Watch Ad";
});
Technical Considerations
1. SDK Placement
Always place the SDK script in the <head>
section of your HTML document:
<head>
<!-- Other head elements -->
<script src="https://gcdn.magfiads.com/magfi.min.js"></script>
</head>
2. Unique AD_CODE Usage
Use each AD_CODE
only once per page. Using the same code multiple times can cause unpredictable behavior.
3. Error Handling
Implement comprehensive error handling for all ad-related operations:
try {
const adInstance = magfi.add({ code: "AD_CODE" });
adInstance.addEventListener("onError", (error) => {
console.error("Ad error:", error);
// Handle error appropriately
});
} catch (error) {
console.error("Failed to initialize ad:", error);
// Fallback behavior
}
4. Testing Strategy
Test your ad implementation thoroughly:
- Test with network throttling to simulate slow connections
- Test when ads are unavailable
- Test frequency capping logic
- Test in different browsers and devices
Performance Optimization
1. Lazy Initialization
For ads that don't need to be immediately available, consider lazy initialization:
// Initialize ad only when needed
function initializeAd() {
if (!adInstance) {
adInstance = magfi.add({ code: "AD_CODE" });
adInstance.addEventListener("onReady", () => {
adButton.disabled = false;
});
}
}
// Call when appropriate, e.g. when user navigates to a section with ads
showAdSectionButton.addEventListener("click", () => {
showAdSection();
initializeAd();
});
2. Preload Ads Strategically
Preload ads at appropriate times to reduce waiting when the user wants to see an ad:
// For example, in a game, preload the next level's ads during the current level
function startLevel(levelNumber) {
playLevel(levelNumber);
// Preload ad for the end of the level
if (!endOfLevelAd) {
endOfLevelAd = magfi.add({ code: "END_LEVEL_AD_CODE" });
}
}
3. Minimize DOM Manipulations
When working with banner ads, minimize DOM manipulations to avoid affecting ad performance:
// Create a dedicated container once
const adContainer = document.getElementById('ad-container');
// Add the ad to the container
const bannerAd = magfi.add({
code: "BANNER_AD_CODE",
});
Analytics and Monitoring
1. Track Ad Performance
Implement analytics to track ad performance:
ad.addEventListener("onReady", () => {
trackEvent("ad_ready", { adType: "rewarded" });
});
ad.addEventListener("onStart", () => {
trackEvent("ad_start", { adType: "rewarded" });
});
ad.addEventListener("onClose", () => {
trackEvent("ad_close", { adType: "rewarded" });
});
ad.addEventListener("onSkip",()=>{
trackEvent("ad_skipped", { adType: "rewarded" });
})
ad.addEventListener("adNotFound", () => {
trackEvent("ad_not_found", { adType: "rewarded" });
});
2. Monitor Fill Rate
Keep track of ad fill rates to optimize your implementation:
let adRequests = 0;
let adFills = 0;
function requestAd() {
adRequests++;
const ad = magfi.add({ code: "AD_CODE" });
ad.addEventListener("onReady", () => {
adFills++;
updateFillRate();
});
ad.addEventListener("adNotFound", () => {
updateFillRate();
});
}
function updateFillRate() {
const fillRate = (adFills / adRequests) * 100;
console.log(`Current fill rate: ${fillRate.toFixed(2)}%`);
}