Como detectar adblock y mostrar aviso respetuoso con JS en WordPress

Contents

Introducción

Este tutorial explica, paso a paso y con todo lujo de detalles, cómo detectar si un visitante utiliza un bloqueador de anuncios (adblock) en WordPress y cómo mostrar un aviso respetuoso usando JavaScript. Incluye varias técnicas de detección, ejemplos completos de código (listos para copiar/pegar), cómo integrarlo en un tema o plugin de WordPress y recomendaciones de usabilidad y accesibilidad. El objetivo es informar educadamente al usuario sobre el impacto del bloqueador y proponer alternativas sin romper la experiencia.

Por qué detectar adblock y cómo hacerlo respetuosamente

Detectar adblock puede servir para:

  • Mostrar un mensaje pidiendo a usuarios que desactiven adblock o añadan el sitio a la lista blanca.
  • Ofrecer alternativas (suscripción, versión sin anuncios, donación).
  • Medir el impacto de los bloqueadores en los ingresos.

Recomendaciones de respeto:

  • Evitar bloqueos forzosos o paywalls completos por defecto.
  • Usar mensajes cortos, claros y amables.
  • Proporcionar instrucciones sencillas para desactivar o whitelist el sitio.
  • Garantizar accesibilidad para lectores de pantalla y navegación por teclado.

Métodos de detección (pros y contras)

  1. Bait element (elemento cebado): crear un elemento con clases/id comunes a anuncios (por ejemplo ad, ads, adunit) y comprobar si ha sido ocultado/eliminado.

    • Pros: rápido, sin peticiones de red.
    • Contras: puede dar falsos positivos/negativos con ciertos estilos del tema.
  2. Petición a recurso bloqueado: intentar cargar un recurso con URL similar a la de anuncios (por ejemplo /ads.js o un endpoint de publicidad) y detectar si falla.

    • Pros: fiable si el bloqueador bloquea el patrón de URL.
    • Contras: requiere recurso adicional o control sobre la URL puede añadir latencia.
  3. Comprobar variables globales de redes de anuncios: muchas redes exponen objetos globales si faltan, es posible que el script haya sido bloqueado.

    • Pros: útil si realmente usas esa red de anuncios.
    • Contras: dependiente del proveedor, no universal.
  4. Combinación de métodos: usar dos métodos para reducir falsos positivos.

Ejemplo 1 — Detección con bait element (método recomendado por simplicidad)

Este script crea un elemento cebado, espera un breve momento y comprueba estilos y existencia para inferir si un bloqueador lo ha eliminado u ocultado. Si detecta bloqueo, ejecuta una función para mostrar el aviso.

(function () {
  // Tiempo de espera en ms antes de evaluar el bait
  var WAIT = 150

  function createBait() {
    var bait = document.createElement(div)
    // Usamos nombres típicos que los adblockers suelen bloquear
    bait.className = ad-banner adsbox adunit advertisement
    bait.id = ads-test-bait
    // Lo posicionamos fuera de la pantalla para no interferir
    bait.style.position = absolute
    bait.style.left = -9999px
    bait.style.width = 1px
    bait.style.height = 1px
    document.body.appendChild(bait)
    return bait
  }

  function checkBait(bait) {
    var blocked = false
    // Si el elemento fue eliminado por el adblock
    if (!document.body.contains(bait)) {
      blocked = true
    } else {
      var style = window.getComputedStyle(bait)
      // Si el estilo indica display:none o visibilidad ocultada o tamaño 0
      if (style  (style.display === none  style.visibility === hidden  bait.offsetParent === null  bait.offsetHeight === 0  bait.offsetWidth === 0)) {
        blocked = true
      }
    }
    try {
      document.body.removeChild(bait)
    } catch (e) { / ignore / }
    return blocked
  }

  function showAdblockNotice() {
    // Lógica para mostrar aviso: aquí solo llamamos a window.dispatchEvent
    // para que la integración en WordPress pueda escuchar y mostrar el UI
    var event
    try {
      event = new CustomEvent(adblockDetected, { detail: { detected: true } })
    } catch (e) {
      event = document.createEvent(Event)
      event.initEvent(adblockDetected, true, true)
      event.detail = { detected: true }
    }
    window.dispatchEvent(event)
  }

  // Ejecutar detection tras DOMContentLoaded o cuando el body exista
  function runDetection() {
    if (!document.body) {
      document.addEventListener(DOMContentLoaded, runDetection)
      return
    }
    var bait = createBait()
    setTimeout(function () {
      if (checkBait(bait)) {
        showAdblockNotice()
      }
    }, WAIT)
  }

  runDetection()
})()

Ejemplo 2 — Detección mediante carga de recurso (más robusto contra algunos bloqueadores)

Este enfoque intenta cargar un archivo que normalmente sería bloqueado por un adblock (por ejemplo, con ruta que contenga ads). Usamos fetch para comprobar si la petición llega a su fin o es bloqueada.

(function () {
  var TEST_URL = /ads-test.js // URL en tu servidor que devuelve 200 OK (vacía o con JSON)
  var TIMEOUT = 1800 // ms

  function fetchWithTimeout(url, timeout) {
    return new Promise(function (resolve) {
      var done = false
      var timer = setTimeout(function () {
        if (done) return
        done = true
        resolve({ ok: false, status: 0, reason: timeout })
      }, timeout)

      fetch(url, { method: HEAD, cache: no-store }).then(function (res) {
        if (done) return
        done = true
        clearTimeout(timer)
        resolve({ ok: res.ok, status: res.status })
      }).catch(function (err) {
        if (done) return
        done = true
        clearTimeout(timer)
        resolve({ ok: false, status: 0, reason: err  err.message })
      })
    })
  }

  fetchWithTimeout(TEST_URL, TIMEOUT).then(function (res) {
    // Si la petición no ha llegado (bloqueo del cliente) entonces adblock probable
    if (!res.ok  res.status === 0) {
      var event
      try {
        event = new CustomEvent(adblockDetected, { detail: { detected: true, method: fetch } })
      } catch (e) {
        event = document.createEvent(Event)
        event.initEvent(adblockDetected, true, true)
        event.detail = { detected: true, method: fetch }
      }
      window.dispatchEvent(event)
    }
  })
})()

Mostrar un aviso respetuoso en la página

El ejemplo a continuación muestra cómo crear, estilizar y exponer un aviso accesible cuando se detecta un adblock. El estilo debe integrarse en tu tema o en CSS encolado. Aquí mostramos un ejemplo básico de HTML CSS JS (todo en fragmentos separados para que lo adaptes).

CSS del aviso

/ Estilos básicos: ajusta colores y tamaños según diseño /
.adblock-notice {
  position: fixed
  right: 20px
  bottom: 20px
  max-width: 360px
  background: #fff
  color: #111
  border: 1px solid rgba(0,0,0,0.08)
  box-shadow: 0 6px 18px rgba(0,0,0,0.08)
  padding: 14px
  border-radius: 8px
  z-index: 99999
  font-family: system-ui, -apple-system, Segoe UI, Roboto, Helvetica Neue, Arial
}
.adblock-notice h4 {
  margin: 0 0 6px 0
  font-size: 16px
}
.adblock-notice p {
  margin: 0 0 10px 0
  font-size: 14px
}
.adblock-notice .adblock-actions {
  text-align: right
}
.adblock-notice .adblock-btn {
  background: #0066cc
  color: white
  padding: 8px 10px
  border-radius: 6px
  text-decoration: none
  margin-left: 6px
  display: inline-block
  font-size: 13px
}
.adblock-notice .adblock-link {
  color: #0066cc
  text-decoration: underline
  font-size: 13px
}

HTML del aviso (fragmento que puedes insertar con PHP)


JavaScript para mostrar el aviso cuando se dispare el evento

// Escuchar el evento global adblockDetected disparado por nuestros detectores
window.addEventListener(adblockDetected, function (e) {
  var notice = document.getElementById(adblock-notice)
  if (!notice) return
  // Mostrar el aviso
  notice.style.display = block
  // Foco para accesibilidad
  notice.setAttribute(tabindex, -1)
  notice.focus()

  // Botón / enlace para cerrar o posponer
  var dismiss = document.getElementById(adblock-dismiss)
  if (dismiss) {
    dismiss.addEventListener(click, function (ev) {
      ev.preventDefault()
      notice.style.display = none
      // Guardar preferencia localmente para no molestar en la misma sesión
      try { localStorage.setItem(adblockNoticeDismissed, Date.now()) } catch (e) {}
    }, { once: true })
  }
})

Integración en WordPress

Para integrar con WordPress hay dos puntos: encolar los scripts y añadir el HTML del aviso en el footer o mediante un hook. A continuación un ejemplo de cómo hacerlo en functions.php o en un pequeño plugin.

PHP: encolar scripts y añadir HTML en el footer

 home_url(/ads-test.js)
  ))
}
add_action(wp_enqueue_scripts, mytheme_enqueue_adblock_detection)

// Añadir el HTML del aviso en el footer para que esté disponible
function mytheme_adblock_notice_html() {
  ?>
  
  

Archivo de prueba ads-test.js

Si usas la técnica de fetch, crea un endpoint simple que devuelva 200. Un ejemplo minimal en PHP (por si el servidor soporta PHP):


Buenas prácticas y consideraciones

  • No utilizar tácticas agresivas: forzar bloqueos o despreciar al usuario suele perjudicar la retención.
  • Soporte y alternativas: ofrece instrucciones claras y enlaces a opciones de pago o donaciones.
  • Persistencia razonable: guarda la preferencia de recordar más tarde en localStorage o cookies con vencimiento razonable para no molestar.
  • Combinación de detecciones: usar bait fetch reduce falsos positivos.
  • Pruebas: probar con distintos bloqueadores (uBlock, AdBlock Plus, AdGuard) y en móviles.
  • Privacidad y GDPR: no recopilar datos personales sin consentimiento si recopilas estadísticas sobre detección, anonimízalas.
  • Accesibilidad: usar role=dialog, aria-labelledby y gestionar foco para lectores de pantalla.

Cómo evitar falsos positivos y problemas

  1. Usar nombres de clase que no choquen con tu CSS: el bait debe ser invisible y fuera del flujo.
  2. No depender únicamente de una sola comprobación combinar técnicas.
  3. Probar con temas y plugins que puedan alterar estilos (por ejemplo, themes que oculten anuncios según el layout).
  4. Controlar el timing: algunos bloqueadores actúan al cargar recursos, otros aplican reglas después ajustar el timeout con prudencia.

Ejemplo completo de flujo recomendado

  • Encolar CSS JS desde functions.php.
  • Incluir HTML del aviso en wp_footer.
  • Usar ambos detectores: bait element y fetch a /ads-test.js.
  • Cuando se detecta, mostrar aviso accesible y registrar la interacción (sin datos personales).
  • Ofrecer alternativas: cómo desactivar, suscripciones o donar.

Testing y depuración

Consejos para probar:

  • Habilitar y deshabilitar extensiones de adblock localmente.
  • Usar herramientas como las devtools para comprobar si el bait se elimina o si la petición fetch falla.
  • Revisar consola por errores y registrar eventos personalizados (por ejemplo, console.log cuando se detecta adblock).

Limitaciones y ética

Detectar adblock no debe usarse para perseguir o acosar visitantes. Muchas personas usan bloqueadores por privacidad o velocidad. La mejor estrategia suele ser la transparencia y ofrecer opciones: explicar por qué los anuncios ayudan y dar alternativas.

Conclusión

Detectar adblock y mostrar un aviso respetuoso en WordPress es perfectamente viable con técnicas sencillas (bait element, comprobación de recursos) y una integración limpia mediante wp_enqueue_scripts y wp_footer. Implementa mensajes accesibles y no intrusivos, combina métodos para evitar falsos positivos y ofrece alternativas a los usuarios. Los ejemplos de código incluidos son plantillas listas para adaptar a tu tema o plugin.



Acepto donaciones de BAT's mediante el navegador Brave 🙂



Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *