Saltar para o conteúdo principal

Anúncios intersticiais de página inteira em aplicações de página única

Este guia demonstra como implementar anúncios Full Page Interstitial (FPI) numa aplicação de página única (SPA) utilizando chamadas diretas à API. Funciona com React, Vue, Angular e outras estruturas.

Full Page Interstitial (FPI) Ads in Single Page Applications

Implementação passo-a-passo

Passo 1: Configurar o estado dos componentes

Em primeiro lugar, crie variáveis de estado para controlar o sistema de anúncios e a navegação:

'use client'

import { useEffect, useState } from 'react'

export default function HomePage() {
const [adLoaded, setAdLoaded] = useState(false)
const [currentPage, setCurrentPage] = useState('home')

useEffect(() => {
setAdLoaded(true)
console.log('✅ FPI API method initialized')
}, [])
}

Passo 2: Criar função de pedido de API

Esta função faz um pedido HTTP direto ao servidor de anúncios FPI:

const triggerFPIAd = async () => {
console.log('🎯 Making direct API call to FPI service...')

try {
// Prepare request with user context
const requestBody = {
user: {
ua: navigator.userAgent,
language: navigator.language || 'en-US',
referer: window.location.href,
consumer: 'ad-provider',
gdpr: { gdpr: 0 },
screen_resolution: `${screen.width}x${screen.height}`,
window_orientation: screen.width > screen.height ? 'landscape' : 'portrait',
cookies: [],
scr_info: btoa('async||3')
},
zones: [{
custom_targeting: {},
id: 1234567, // Your FPI Zone ID (use mobile FPI zone ID for mobile devices)
extra_params: {
first_request: true,
zone_type: 35 // Interstitial format
}
}]
}

// Make API call
const response = await fetch('https://s.pemsrv.com/v1/api.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody)
})

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}

const data = await response.json()
console.log('📥 Full API Response:', data)

// Process response
if (data.zones && data.zones.length > 0) {
const zone = data.zones[0]

if (zone.data) {
console.log('🎨 Displaying ad...')
await displayInterstitialAd(zone.data)
} else {
console.log('❌ No ad data in response')
}
}

} catch (error) {
console.error('❌ FPI API Error:', error)
}
}

Tratamento da apresentação de anúncios

Passo 3: Criar a função de visualização

Esta função processa vários formatos de anúncios

const displayInterstitialAd = async (adData: any) => {
console.log('🎨 Starting to display interstitial ad...')

try {
// Remove any existing overlay
const existingOverlay = document.getElementById('fpi-interstitial-overlay')
if (existingOverlay) {
document.body.removeChild(existingOverlay)
}

// Create fullscreen overlay
const overlay = document.createElement('div')
overlay.id = 'fpi-interstitial-overlay'
overlay.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.9);
z-index: 999999;
display: flex;
align-items: center;
justify-content: center;
`

// Create ad container
const adContainer = document.createElement('div')
adContainer.style.cssText = `
position: relative;
width: 100vw;
height: 100vh;
background: white;
overflow: hidden;
`

// Create close button
const closeButton = document.createElement('button')
closeButton.innerHTML = '✕'
closeButton.style.cssText = `
position: absolute;
top: 10px;
right: 10px;
width: 40px;
height: 40px;
border: none;
background: rgba(0, 0, 0, 0.7);
color: white;
font-size: 20px;
border-radius: 50%;
cursor: pointer;
z-index: 1000000;
`

closeButton.onclick = () => {
document.body.removeChild(overlay)
console.log('🚪 Interstitial ad closed')
}

// Determine ad format and create content
let adContent = ''

// Format 1: Iframe Ad
if (adData.html && adData.html.includes('iframe.php')) {
adContent = `
<iframe
src="${adData.html}"
width="100%"
height="100%"
frameborder="0"
allowfullscreen
sandbox="allow-scripts allow-forms allow-popups"
style="width: 100vw; height: 100vh; border: none;"
></iframe>
`
console.log('🖼️ Created iframe ad')
}
Click to expand additional ad formats
    if (adData.html && adData.html.includes('iframe.php')) {
adContent = `
<iframe
src="${adData.html}"
width="100%"
height="100%"
frameborder="0"
allowfullscreen
sandbox="allow-scripts allow-forms allow-popups"
style="width: 100vw; height: 100vh; border: none;"
></iframe>
`
console.log('🖼️ Created iframe ad')
}

// Format 2: Video Ad
else if (adData.video) {
const hasClickUrl = adData.url && adData.url.trim() !== ''

if (hasClickUrl) {
// Video with click-through
adContent = `
<div style="position: relative; width: 100vw; height: 100vh; cursor: pointer;"
onclick="window.open('${adData.url}', '_blank')">
<video
width="100%"
height="100%"
autoplay
muted
loop
style="object-fit: cover; width: 100vw; height: 100vh;"
>
<source src="${adData.video}" type="video/mp4">
</video>
<div style="
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 8px 16px;
border-radius: 20px;
font-size: 14px;
">
Click to visit advertiser
</div>
</div>
`
console.log('🎬 Created clickable video banner ad')
} else {
// Regular video
adContent = `
<video
width="100%"
height="100%"
autoplay
muted
controls
style="object-fit: cover; width: 100vw; height: 100vh;"
>
<source src="${adData.video}" type="video/mp4">
</video>
`
console.log('🎬 Created video ad')
}
}

// Format 3: Click-Through Ad
else if (adData.url) {
adContent = `
<div style="
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background: linear-gradient(45deg, #0072ba, #28a745);
padding: 20px;
">
<h2 style="color: white; margin-bottom: 20px; font-size: 48px;">
🎯 Interstitial Ad
</h2>
<p style="color: white; margin-bottom: 30px; font-size: 24px;">
Click to visit advertiser
</p>
<a href="${adData.url}"
target="_blank"
style="
padding: 15px 30px;
background: white;
color: #0072ba;
text-decoration: none;
border-radius: 25px;
font-weight: bold;
font-size: 18px;
">
Visit Now
</a>
</div>
`
console.log('🔗 Created click-through ad')
}

// Format 4: Native Ads
else if (adData.ad_items && adData.ad_items.length > 0) {
const adItemsHtml = adData.ad_items.map((item: any) => `
<div style="
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
cursor: pointer;
" onclick="window.open('${item.url}', '_blank')">
<div style="height: 200px; overflow: hidden;">
<img src="${item.optimum_image || item.image}"
style="width: 100%; height: 100%; object-fit: cover;"
alt="${item.title}">
</div>
<div style="padding: 15px;">
<h3 style="margin: 0 0 8px 0; font-size: 18px;">${item.title}</h3>
${item.description ? `<p style="font-size: 14px; color: #666;">${item.description}</p>` : ''}
<div style="font-size: 12px; color: #999;">${item.brand || 'Sponsored'}</div>
</div>
</div>
`).join('')

adContent = `
<div style="
width: 100vw;
height: 100vh;
background: #f5f5f5;
overflow-y: auto;
padding: 20px;
">
<h2 style="text-align: center; margin-bottom: 20px;">Sponsored Content</h2>
<div style="
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px;
">
${adItemsHtml}
</div>
</div>
`
console.log('🎯 Created native ad grid')
}

// Add content to container
adContainer.innerHTML = adContent
adContainer.appendChild(closeButton)
overlay.appendChild(adContainer)
document.body.appendChild(overlay)

// Track impression
if (adData.impression) {
fetch(adData.impression, { method: 'GET', mode: 'no-cors' })
.then(() => console.log('📊 Impression tracked'))
.catch(e => console.log('⚠️ Impression tracking failed:', e))
}

} catch (error) {
console.error('❌ Error displaying ad:', error)
}
}

Passo 4: Adicionar botão de acionamento

return (
<div>
<h1>My Page</h1>
<button onClick={triggerFPIAd}>
Load FPI Ad
</button>
</div>
)

Exemplo de código completo

Pronto para o ver em ação? Veja a nossa demonstração interactiva que combina todos os passos acima numa implementação funcional.

Demonstração em direto: Ver código e sítio de demonstração

Full Page Interstitial (FPI) Ads in Single Page Applications