Anuncios intersticiales de página completa en aplicaciones de una sola página
AnteriorIntegración de zonas publicitarias de ExoClick con Vue.jsSiguienteCómo mostrar anuncios SFW con ExoClick
Última actualización
¿Te fue útil?
¿Te fue útil?
'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('✅ Método de API FPI inicializado')
}, [])
}const triggerFPIAd = async () => {
console.log('🎯 Realizando llamada directa a la API al servicio FPI...')
try {
// Preparar la solicitud con el contexto del usuario
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, // Tu ID de zona FPI (usa el ID de zona FPI móvil para dispositivos móviles)
extra_params: {
first_request: true,
zone_type: 35 // Formato intersticial
}
}]
}
// Realizar llamada a la API
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('📥 Respuesta completa de la API:', data)
// Procesar respuesta
if (data.zones && data.zones.length > 0) {
const zone = data.zones[0]
if (zone.data) {
console.log('🎨 Mostrando anuncio...')
await displayInterstitialAd(zone.data)
} else {
console.log('❌ No hay datos de anuncio en la respuesta')
}
}
} catch (error) {
console.error('❌ Error de la API FPI:', error)
}
}const displayInterstitialAd = async (adData: any) => {
console.log('🎨 Iniciando la visualización del anuncio intersticial...')
try {
// Eliminar cualquier superposición existente
const existingOverlay = document.getElementById('fpi-interstitial-overlay')
if (existingOverlay) {
document.body.removeChild(existingOverlay)
}
// Crear una superposición de pantalla completa
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;
`
// Crear contenedor del anuncio
const adContainer = document.createElement('div')
adContainer.style.cssText = `
position: relative;
width: 100vw;
height: 100vh;
background: white;
overflow: hidden;
`
// Crear botón de cierre
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('🚪 Anuncio intersticial cerrado')
}
// Determinar el formato del anuncio y crear el contenido
let adContent = ''
// Formato 1: Anuncio en iframe
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('🖼️ Anuncio en iframe creado')
} 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('🖼️ Anuncio en iframe creado')
}
// Formato 2: Anuncio de video
else if (adData.video) {
const hasClickUrl = adData.url && adData.url.trim() !== ''
if (hasClickUrl) {
// Video con redirección al hacer clic
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;
">
Haz clic para visitar al anunciante
</div>
</div>
`
console.log('🎬 Anuncio de video banner clicable creado')
} else {
// Video normal
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('🎬 Anuncio de video creado')
}
}
// Formato 3: Anuncio con redirección al hacer clic
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;">
🎯 Anuncio intersticial
</h2>
<p style="color: white; margin-bottom: 30px; font-size: 24px;">
Haz clic para visitar al anunciante
</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;
">
Visitar ahora
</a>
</div>
`
console.log('🔗 Anuncio con redirección al hacer clic creado')
}
// Formato 4: Anuncios nativos
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 || 'Patrocinado'}</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;">Contenido patrocinado</h2>
<div style="
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px;
">
${adItemsHtml}
</div>
</div>
`
console.log('🎯 Cuadrícula de anuncios nativos creada')
}
// Añadir contenido al contenedor
adContainer.innerHTML = adContent
adContainer.appendChild(closeButton)
overlay.appendChild(adContainer)
document.body.appendChild(overlay)
// Registrar impresión
if (adData.impression) {
fetch(adData.impression, { method: 'GET', mode: 'no-cors' })
.then(() => console.log('📊 Impresión registrada'))
.catch(e => console.log('⚠️ Falló el seguimiento de la impresión:', e))
}
} catch (error) {
console.error('❌ Error al mostrar el anuncio:', error)
}
}return (
<div>
<h1>Mi página</h1>
<button onClick={triggerFPIAd}>
Cargar anuncio FPI
</button>
</div>
)