Saltar al contenido
Lunes a viernes, 9:00–19:00 (CDMX) hola@nebu-lab.com  ·  +52 55 3121 2956
55 3121 2956 Diagnóstico gratis

Glosario SEO 2026 — 60+ Términos Explicados Simple

.nl-glo{max-width:1100px;margin:0 auto;padding:20px;font-family:-apple-system,Segoe UI,Arial,sans-serif} .nl-glo-hero{background:linear-gradient(135deg,#0a0f1e,#1a2547);color:#fff;padding:50px 40px;border-radius:20px;text-align:center;margin-bottom:30px} .nl-glo-hero h1{font-size:clamp(28px,4.5vw,42px);margin:0 0 14px;font-weight:800;line-height:1.15} .nl-glo-hero p{font-size:17px;opacity:.9;max-width:640px;margin:0 auto 20px} .nl-glo-search{max-width:520px;margin:0 auto;position:relative} .nl-glo-search input{width:100%;padding:16px 20px 16px 50px;border:0;border-radius:12px;font-size:16px;box-sizing:border-box} .nl-glo-search::before{content:»🔍»;position:absolute;left:18px;top:50%;transform:translateY(-50%);font-size:18px} .nl-glo-letters{display:flex;flex-wrap:wrap;gap:6px;justify-content:center;margin:0 0 26px} .nl-glo-letters a{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;background:#f6f8fc;color:#0066ff;border-radius:8px;text-decoration:none;font-weight:700;font-size:14px;transition:all .15s} .nl-glo-letters a:hover{background:#0066ff;color:#fff} .nl-glo-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));gap:16px} .nl-glo-item{background:#fff;padding:20px 22px;border-radius:12px;border-left:4px solid #0066ff;box-shadow:0 2px 10px rgba(0,0,0,.04);transition:transform .15s} .nl-glo-item:hover{transform:translateY(-2px);box-shadow:0 6px 20px rgba(0,0,0,.08)} .nl-glo-item h3{margin:0 0 6px;color:#0a0f1e;font-size:18px} .nl-glo-item .letter{font-size:11px;letter-spacing:2px;color:#0066ff;font-weight:800;margin-bottom:2px} .nl-glo-item p{margin:0;color:#444;font-size:14px;line-height:1.55} .nl-glo-cta{background:linear-gradient(135deg,#0066ff,#00aaff);color:#fff;padding:40px;border-radius:16px;text-align:center;margin-top:40px} .nl-glo-cta h2{color:#fff;margin:0 0 10px;font-size:26px} .nl-glo-cta p{margin:0 0 20px;opacity:.95} .nl-glo-cta a{display:inline-block;background:#fff;color:#0066ff;padding:14px 28px;border-radius:10px;font-weight:800;text-decoration:none;margin:0 6px} .nl-glo-cta a.wa{background:#25D366;color:#fff} .hide{display:none}
📚 GLOSARIO SEO 2026

Glosario SEO — 60+ Términos Explicados Simple

El diccionario SEO más completo en español. Desde lo básico (backlink, keyword) hasta lo avanzado (GEO, E-E-A-T, Core Web Vitals 2026).

¿Quieres implementar todo esto en tu web?

Nuestros expertos aplican todo el glosario para posicionarte en Google. +200 proyectos, +15 años, 4.9/5.

Auditar mi web gratis
var nlGlo=[ {t:»301 Redirect»,d:»Redirección permanente de una URL a otra. Transfiere prácticamente todo el link equity (PageRank). Esencial en migraciones y cambios de URL.»}, {t:»404 Error»,d:»Código HTTP que indica página no encontrada. Exceso de 404 daña UX y rastreo. Usa redirecciones o páginas 404 útiles con enlaces.»}, {t:»Algoritmo de Google»,d:»Sistema complejo que determina el ranking de páginas en búsquedas. Principales: PageRank, Hummingbird, RankBrain, BERT, MUM, SpamBrain.»}, {t:»AI Overviews»,d:»Resultados generados por IA en la parte superior de Google Search. Evolución del Search Generative Experience (SGE). Citan fuentes.»}, {t:»Anchor Text»,d:»Texto visible y clickeable de un enlace. El anchor envía señales de relevancia. Mezcla anchors de marca, URL desnuda, naturales y de keyword.»}, {t:»Authority Site»,d:»Sitio con alta autoridad en un nicho. Características: backlinks de calidad, contenido experto, antigüedad, señales E-E-A-T.»}, {t:»Backlink»,d:»Enlace desde otro sitio apuntando al tuyo. Principal señal de autoridad. Importa calidad (DA/DR, relevancia, tráfico) no cantidad.»}, {t:»Bing Webmaster Tools»,d:»Plataforma gratuita de Microsoft para Bing. Equivalente a Search Console. Esencial para aparecer en Copilot y ChatGPT Search.»}, {t:»Black Hat SEO»,d:»Técnicas que violan las directrices de buscadores (cloaking, PBNs baratas, keyword stuffing). Riesgo: penalización manual o algorítmica.»}, {t:»Bounce Rate»,d:»% de visitantes que abandonan sin interactuar. En GA4 reemplazado por ‘engagement rate’. Alto bounce no siempre es malo (depende intención).»}, {t:»Canonical URL»,d:»Etiqueta rel=canonical que indica la URL preferida entre duplicados. Previene canibalización y consolida señales. Clave en e-commerce.»}, {t:»Citation»,d:»Mención de nombre+dirección+teléfono (NAP) en directorios. Importante para SEO local. Consistencia NAP fundamental.»}, {t:»Cloaking»,d:»Mostrar contenido distinto a bots vs usuarios. Black hat, penalización segura. No confundir con personalización legítima.»}, {t:»Content Gap»,d:»Temas que cubren competidores pero tú no. Herramientas: Ahrefs Content Gap, Semrush, manual en SERP. Plan de contenido basado en gaps.»}, {t:»Core Update»,d:»Actualización mayor del algoritmo de Google (marzo, agosto, diciembre típicamente). Impacta rankings significativamente. Recuperación con mejora E-E-A-T.»}, {t:»Core Web Vitals»,d:»Métricas de UX de Google: LCP (carga), INP (interactividad, reemplazó FID en 2024), CLS (estabilidad). Afectan ranking directamente.»}, {t:»Crawl Budget»,d:»Cantidad de URLs que Googlebot rastrea en un periodo. Importante en sitios grandes (100K+ URLs). Optimizar con sitemap, robots, internal linking.»}, {t:»Crawlability»,d:»Capacidad de bots para rastrear tu sitio. Depende de robots.txt, estructura, enlaces, renderizado JS. Sin crawlabilidad, no hay indexación.»}, {t:»CTR (Click-Through Rate)»,d:»% de impresiones que generan clic. Visible en GSC. Bajo CTR vs media de posición = oportunidad de mejorar title/description/schema.»}, {t:»Disavow Tool»,d:»Herramienta de Google para descartar backlinks tóxicos. Usar con cuidado — Google es mejor filtrando spam automáticamente que antes.»}, {t:»Domain Authority (DA)»,d:»Métrica 0-100 de Moz que predice ranking. No es oficial Google. Ahrefs tiene Domain Rating (DR). Útil comparativamente.»}, {t:»Dwell Time»,d:»Tiempo entre clic y regreso a SERP. Señal de satisfacción. Aumenta con contenido útil, multimedia, buena UX.»}, {t:»E-E-A-T»,d:»Experience, Expertise, Authoritativeness, Trustworthiness. Directrices de calidad de Google. Crítico en YMYL (salud, finanzas, legal).»}, {t:»Entidades»,d:»Conceptos identificables (personas, lugares, marcas, ideas). Google piensa en entidades, no solo keywords. Optimiza con Wikipedia, schema, menciones.»}, {t:»Evergreen Content»,d:»Contenido que mantiene relevancia en el tiempo. Opuesto a noticias. Ejemplos: guías, definiciones, tutoriales fundamentales.»}, {t:»Featured Snippet»,d:»Respuesta destacada en posición cero. Formatos: párrafo, lista, tabla, video. Captura 8-12% del CTR de la SERP.»}, {t:»GEO (Generative Engine Optimization)»,d:»Optimización para aparecer citado en ChatGPT, Perplexity, AI Overviews, Claude. Tácticas: llms.txt, contenido estructurado, citabilidad, data propios.»}, {t:»Google Business Profile (GBP)»,d:»Ficha gratuita de Google para negocios locales (antes GMB). Clave para Map Pack y búsquedas ‘cerca de mí’.»}, {t:»Google Discover»,d:»Feed personalizado de Google mobile. Tráfico masivo sin keywords. Requiere imágenes grandes (1200px), contenido ‘noticioso’ y engagement.»}, {t:»Google Search Console (GSC)»,d:»Plataforma gratuita de Google con datos de rendimiento, indexación, Core Web Vitals, enlaces. Imprescindible.»}, {t:»Header Tags (H1-H6)»,d:»Jerarquía de encabezados HTML. H1 único por página con keyword principal. H2-H3 estructuran secciones. Mejora semántica y UX.»}, {t:»Hreflang»,d:»Atributo que indica versión idiomática/regional. Crítico en sitios multi-país/idioma. Errores comunes: códigos incorrectos, falta reciprocidad.»}, {t:»HTTPS»,d:»Protocolo seguro con SSL/TLS. Factor de ranking confirmado desde 2014. Imprescindible para confianza de usuarios y formularios.»}, {t:»IndexNow»,d:»Protocolo para notificar actualizaciones a Bing/Yandex instantáneamente. Google no lo acepta aún. Plugins WP lo automatizan.»}, {t:»Information Gain»,d:»Información nueva que tu contenido aporta vs los competidores. Patente Google 2022. Diferencia contenido copiado de contenido valioso.»}, {t:»Internal Linking»,d:»Enlaces dentro del mismo dominio. Distribuye link equity, mejora rastreo, define jerarquía. Clave: anchor relevante, desde páginas potentes.»}, {t:»Intent (Intención de búsqueda)»,d:»Objetivo del usuario al buscar. Tipos: informacional, navegacional, comercial, transaccional. Alinea contenido con intención o no rankeas.»}, {t:»JSON-LD»,d:»Formato preferido por Google para Schema.org. Script en . Más fácil de mantener que microdata. Enriquece SERP con rich results.»}, {t:»Keyword Difficulty (KD)»,d:»Estimación 0-100 de dificultad para rankear. Métrica de terceros (Ahrefs, Semrush, Moz). Útil priorizar pero no confiar ciegamente.»}, {t:»Keyword Research»,d:»Proceso de identificar términos que tu audiencia busca. Base de toda estrategia SEO. Herramientas: GSC, Ahrefs, Semrush, AnswerThePublic.»}, {t:»Link Building»,d:»Obtención estratégica de backlinks. Tácticas: guest posts, HARO, link insertion, digital PR, broken link. Evitar PBN baratas.»}, {t:»Link Equity»,d:»Valor SEO transferido entre páginas vía enlaces. Aka ‘link juice’. Se distribuye por la estructura. No transfieren los nofollow.»}, {t:»Local Pack»,d:»Bloque de 3 resultados locales con mapa. Requiere GBP optimizado, NAP consistente, reviews, proximidad. Captura 42% de clics móviles.»}, {t:»Log File Analysis»,d:»Análisis de logs del servidor para ver exactamente qué rastrean los bots. Revela problemas de crawl budget y páginas ignoradas.»}, {t:»Long-tail Keyword»,d:»Frase de 4+ palabras con bajo volumen pero alta conversión. Menos competencia. Conjunto de long-tails = tráfico masivo.»}, {t:»LSI Keywords»,d:»Latent Semantic Indexing keywords. Términos relacionados semánticamente. Moderno: entidades y co-ocurrencia, no LSI literal.»}, {t:»Meta Description»,d:»Resumen de 140-160 caracteres en . No factor ranking directo pero afecta CTR. Google puede reescribir. Optimiza con CTA.»}, {t:»Mobile-First Indexing»,d:»Google indexa primero la versión móvil. Activo por defecto desde 2020. Tu móvil es tu sitio oficial para Google.»}, {t:»NAP Consistency»,d:»Name, Address, Phone consistentes en web, GBP y directorios. Fundamental en SEO local. Inconsistencias confunden al algoritmo.»}, {t:»Noindex»,d:»Directiva meta robots que impide indexación. Útil en páginas thin, filtros, staging. No bloquea crawl — usa robots.txt para eso.»}, {t:»Organic Search»,d:»Tráfico de clics en resultados no pagados de buscadores. El objetivo principal del SEO. Contrasta con Paid Search (SEM).»}, {t:»Page Speed / PageSpeed Insights»,d:»Herramienta gratis de Google con diagnóstico Core Web Vitals + recomendaciones. Móvil y desktop. Base del SEO técnico moderno.»}, {t:»PBN (Private Blog Network)»,d:»Red de sitios propios que enlazan al principal. Técnica black/grey hat. Riesgo alto de penalización. Google detecta patrones.»}, {t:»People Also Ask (PAA)»,d:»Bloque de preguntas en SERP. Fuente de ideas de contenido. Aparecer aumenta CTR y visibilidad.»}, {t:»Pillar Page»,d:»Contenido extenso (3000-8000 palabras) sobre tema central, con clusters de contenido relacionado enlazando. Estructura SEO moderna.»}, {t:»Rank Math»,d:»Plugin SEO WordPress. Alternativa a Yoast con más features gratis. Muy usado en México y LatAm.»}, {t:»Rich Results»,d:»Resultados enriquecidos en SERP (estrellas, FAQ, video, product). Se logran con Schema.org. Aumentan CTR significativamente.»}, {t:»Robots.txt»,d:»Archivo en raíz que instruye a bots qué rastrear. No bloquea indexación (usa noindex para eso). Sintaxis simple pero errores costosos.»}, {t:»Schema Markup»,d:»Código semántico (Schema.org) que describe contenido a buscadores. Tipos: Organization, Product, FAQ, HowTo, Article, LocalBusiness, Review.»}, {t:»SEMrush»,d:»Suite SEO todo-en-uno. Keyword research, competencia, backlinks, site audit, PPC. Competencia de Ahrefs.»}, {t:»SEO Local»,d:»Optimización para búsquedas geográficas. Incluye GBP, citations, reviews, schema LocalBusiness, páginas por ciudad.»}, {t:»SEO Off-page»,d:»Actividades fuera de tu sitio: link building, menciones, PR digital, redes sociales. Construye autoridad.»}, {t:»SEO On-page»,d:»Optimización dentro de tu sitio: contenido, meta tags, estructura, interlinking, UX. Lo que controlas directamente.»}, {t:»SEO Técnico»,d:»Aspectos de infraestructura: velocidad, rastreo, indexación, HTTPS, schema, Core Web Vitals, renderizado JS. Base de todo SEO.»}, {t:»SERP»,d:»Search Engine Results Page. La página de resultados. Features: orgánicos, Ads, local pack, featured snippet, PAA, knowledge panel, AI Overviews.»}, {t:»Sitemap XML»,d:»Archivo con lista de URLs a indexar. Enviado en GSC + robots.txt. Incluye lastmod para señales de frescura.»}, {t:»Structured Data»,d:»Datos estructurados usando Schema.org. Sinónimo de schema markup. Se valida con Rich Results Test de Google.»}, {t:»Technical Debt SEO»,d:»Acumulación de problemas técnicos (redirects innecesarios, duplicados, thin content, crawl issues). Limita crecimiento futuro.»}, {t:»TF-IDF»,d:»Term Frequency-Inverse Document Frequency. Mide importancia de término en documento vs corpus. Usado en optimización semántica.»}, {t:»Thin Content»,d:»Contenido de bajo valor, corto o duplicado. Penaliza rankings. Soluciones: expandir, consolidar, noindex o eliminar.»}, {t:»Title Tag»,d:»Etiqueta en . Uno de los factores on-page más importantes. 50-60 chars, keyword al inicio, marca al final.»}, {t:»Topical Authority»,d:»Autoridad sobre un tema específico. Se construye con clusters de contenido, backlinks temáticos, menciones, schema, entidades.»}, {t:»Traffic Cost»,d:»Valor estimado del tráfico orgánico si fuera comprado en Ads. Métrica de Ahrefs. Útil para ROI SEO.»}, {t:»UTM Parameters»,d:»Parámetros en URL (?utm_source=…) para tracking en GA4. No afectan SEO (canonical debe apuntar URL limpia).»}, {t:»Voice Search»,d:»Búsquedas por voz (Siri, Alexa, Google Assistant). Queries más largas y conversacionales. Optimizar con FAQs y featured snippets.»}, {t:»Web Core Vitals»,d:»Ver Core Web Vitals.»}, {t:»YMYL»,d:»Your Money or Your Life. Páginas que afectan salud, finanzas, seguridad, felicidad. Google aplica estándares E-E-A-T más estrictos.»}, {t:»Zero-Click Search»,d:»Búsqueda donde el usuario no hace clic (obtiene respuesta en SERP). ~65% del total según SparkToro. GEO responde a esto.»} ]; nlGlo.sort(function(a,b){return a.t.localeCompare(b.t);}); var letters=Array.from(new Set(nlGlo.map(function(x){return x.t.charAt(0).toUpperCase();}))).sort(); document.getElementById(‘nlGloLetters’).innerHTML=letters.map(function(l){return ‘<a href="#nlg-'+l+'">‘+l+’</a>‘;}).join(»); var prev=»;var html=»;nlGlo.forEach(function(x){var L=x.t.charAt(0).toUpperCase();var anchor=L!==prev?’ id=»nlg-‘+L+'»‘:»;prev=L;html+=’<div data-t="'+x.t.toLowerCase()+'"><div class="letter">‘+L+’</div><h3>‘+x.t+’</h3><p>‘+x.d+’</p></div>‘;}); document.getElementById(‘nlGloList’).innerHTML=html; document.getElementById(‘nlGloSearch’).addEventListener(‘input’,function(){var q=this.value.toLowerCase().trim();document.querySelectorAll(‘.nl-glo-item’).forEach(function(el){var m=el.getAttribute(‘data-t’).indexOf(q)>=0||el.textContent.toLowerCase().indexOf(q)>=0;el.classList.toggle(‘hide’,!m);});}); <aside class="nl-cluster" aria-label="Otras herramientas gratis"><h2 class="nl-cluster__t">Otras herramientas gratis</h2><ul class="nl-cluster__l"><li><a href="https://nebu-lab.com/auditor-seo-gratis/">Auditor SEO Gratis</a></li><li><a href="https://nebu-lab.com/quiz-seo/">Quiz SEO</a></li><li><a href="https://nebu-lab.com/herramientas-seo-gratis/">Herramientas SEO Gratis</a></li><li><a href="https://nebu-lab.com/guia-seo-2026-descarga/">Descarga Gratis la Guía SEO México 2026 (PDF 120 páginas)</a></li><li><a href="https://nebu-lab.com/auditor-seo/">Auditor SEO Gratis</a></li></ul></aside></div> </div> </section> <section class="banda" id="contacto"> <div class="wrap"> <h2 class="h2-display" style="margin-bottom:18px">Te decimos qué te frena, <em>gratis.</em></h2> <p class="lede measure" style="margin-bottom:30px">Miramos tu sitio, tu medición y tu competencia, y te mandamos los tres problemas que más te están costando. Sin compromiso.</p> <div class="hero-cta"> <a class="btn btn--primary" href="https://wa.me/5215532007498?text=Hola%2C%20me%20gustar%C3%ADa%20pedir%20el%20diagn%C3%B3stico%20SEO%20gratuito.%20%C2%B7%20Vengo%20de%20nebu-lab.com%2Fglosario-seo%2F">Escribir por WhatsApp →</a> <a class="btn btn--ghost btn--ghost-dark" href="tel:+525531212956">55 3121 2956</a> </div> </div> </section> </main> <footer class="ft"> <div class="wrap"> <div class="ft-top"> <div class="ft-marca"> <span class="logo" style="color:var(--nl-canvas)">Nebu<em>Lab</em></span> <p>Agencia SEO en la Ciudad de México. Posicionamiento web para empresas que quieren demanda, no informes.</p> <p class="meta" style="color:rgba(249,248,244,.6)"> C. Dr. Lucio, Doctores, Cuauhtémoc<br> 06720 Ciudad de México </p> <p style="margin-top:14px"> <a href="mailto:hola@nebu-lab.com">hola@nebu-lab.com</a><br> <a href="tel:+525531212956">+52 55 3121 2956</a> </p> </div> <div> <h4>Servicios</h4> <ul> <li><a href="https://nebu-lab.com/seo/">SEO y posicionamiento</a></li> <li><a href="https://nebu-lab.com/auditoria-seo/">Auditoría SEO</a></li> <li><a href="https://nebu-lab.com/consultoria-seo/">Consultoría SEO</a></li> <li><a href="https://nebu-lab.com/link-building/">Autoridad y enlaces</a></li> <li><a href="https://nebu-lab.com/e-commerce/">SEO para ecommerce</a></li> </ul> </div> <div> <h4>Sectores</h4> <ul> <li><a href="https://nebu-lab.com/seo-para-abogados/">Despachos legales</a></li> <li><a href="https://nebu-lab.com/seo-para-doctores/">Clínicas y consultorios</a></li> <li><a href="https://nebu-lab.com/seo-para-restaurantes/">Restaurantes</a></li> <li><a href="https://nebu-lab.com/seo-para-ecommerce/">Tiendas online</a></li> <li><a href="https://nebu-lab.com/seo-para-inmobiliarias/">Inmobiliarias</a></li> </ul> </div> <div> <h4>Ciudades</h4> <ul> <li><a href="https://nebu-lab.com/agencia-seo-cdmx/">Ciudad de México</a></li><li><a href="https://nebu-lab.com/agencia-seo-guadalajara/">Guadalajara</a></li> </ul> </div> <div> <h4>NebuLab</h4> <ul> <li><a href="https://nebu-lab.com/nosotros/">Quiénes somos</a></li> <li><a href="https://nebu-lab.com/casos-de-exito/">Resultados</a></li> <li><a href="https://nebu-lab.com/precios/">Precios</a></li> <li><a href="https://nebu-lab.com/blog/">Blog</a></li> <li><a href="https://nebu-lab.com/contacto/">Contacto</a></li> </ul> </div> </div> <div class="ft-legal"> <span>© 2026 NebuLab · Agencia SEO en México</span> <span> <a href="https://nebu-lab.com/politica-de-privacidad/">Privacidad</a> · <a href="https://nebu-lab.com/terminos-y-condiciones/">Términos</a> </span> </div> </div> </footer> <script type="speculationrules"> {"prefetch":[{"source":"document","where":{"and":[{"href_matches":"\/*"},{"not":{"href_matches":["\/wp-*.php","\/wp-admin\/*","\/wp-content\/uploads\/*","\/wp-content\/*","\/wp-content\/plugins\/*","\/wp-content\/themes\/nebulab-2026\/*","\/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]} </script> <script> (function () { var c = document.body.className; c = c.replace(/woocommerce-no-js/, 'woocommerce-js'); document.body.className = c; })(); </script> <script id="hostinger-reach-subscription-block-view-js-extra"> var hostinger_reach_subscription_block_data = {"endpoint":"https:\/\/nebu-lab.com\/wp-json\/hostinger-reach\/v1\/contact","nonce":"73f3145b9f","translations":{"thanks":"Gracias por suscribirte.","error":"Algo ha ido mal. Int\u00e9ntalo de nuevo."}}; </script> <script src="https://nebu-lab.com/wp-content/plugins/hostinger-reach/frontend/dist/blocks/subscription-view.js?ver=1779173016" id="hostinger-reach-subscription-block-view-js"></script> <!-- NebuLab Lead Machine --> <div id="nl-widgets-root"> <a id="nl-whatsapp-float" href="https://wa.me/5215532007498?text=Hola+NebuLab%2C+vengo+de+la+web%2C+me+interesa+una+auditor%C3%ADa+SEO+gratis.%0A%0A%E2%80%94+Vengo+de+nebu-lab.com%2Fglosario-seo%2F" target="_blank" rel="noopener nofollow" aria-label="Contactar por WhatsApp"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="28" height="28" fill="#fff"><path d="M20.52 3.48A11.9 11.9 0 0012.04 0C5.5 0 .2 5.3.2 11.84c0 2.09.55 4.13 1.6 5.93L0 24l6.4-1.68a11.82 11.82 0 005.64 1.44h.01c6.53 0 11.84-5.3 11.84-11.84 0-3.16-1.23-6.13-3.37-8.44zM12.05 21.6h-.01a9.76 9.76 0 01-4.97-1.36l-.36-.21-3.79 1 1.01-3.7-.24-.38a9.77 9.77 0 01-1.5-5.21c0-5.4 4.4-9.8 9.82-9.8 2.62 0 5.08 1.02 6.94 2.87a9.76 9.76 0 012.88 6.93c0 5.4-4.4 9.8-9.78 9.86zm5.36-7.33c-.29-.15-1.74-.86-2.01-.96-.27-.1-.47-.15-.66.14-.19.29-.76.96-.93 1.16-.17.19-.34.22-.63.07-.29-.15-1.24-.46-2.36-1.47-.87-.78-1.46-1.74-1.63-2.03-.17-.29-.02-.45.13-.6.13-.13.29-.34.44-.5.15-.17.19-.29.29-.48.1-.19.05-.36-.02-.5-.07-.15-.66-1.58-.9-2.17-.24-.57-.48-.49-.66-.5h-.56c-.19 0-.5.07-.77.36-.27.29-1.02 1-1.02 2.44 0 1.44 1.04 2.83 1.19 3.02.15.19 2.05 3.13 4.97 4.39.69.3 1.23.48 1.66.62.7.22 1.33.19 1.83.12.56-.08 1.74-.71 1.98-1.4.24-.69.24-1.28.17-1.4-.07-.12-.26-.19-.55-.34z"/></svg> </a> <div id="nl-exit-popup" aria-hidden="true"> <div class="nl-exit-card"> <button class="nl-exit-close" aria-label="Cerrar">×</button> <div class="nl-exit-badge">GUÍA GRATIS</div> <h3>¿Te vas sin tu Guía SEO 2026?</h3> <p>Descarga la <strong>Guía SEO México 2026</strong> con 120 páginas: checklist técnico, plantillas de contenido, estrategia de link building y secretos GEO.</p> <form id="nl-exit-form" onsubmit="return NebuLab.submitExit(event)"> <input type="email" name="email" required placeholder="tu@empresa.com" autocomplete="email"> <input type="text" name="nombre" placeholder="Tu nombre"> <button type="submit">Descargar Guía PDF gratis</button> <small>Sin spam. Te enviamos el PDF + 5 emails con estrategias. Cancelas cuando quieras.</small> </form> </div> </div> <div id="nl-sticky-bar" aria-hidden="true"> <span class="nl-sticky-msg">🎁 <strong>Diagnóstico SEO gratis</strong> en 24h — sin compromiso</span> <a class="nl-sticky-cta" href="/auditor-seo-gratis/">Obtener mi diagnóstico →</a> <button class="nl-sticky-close" aria-label="Cerrar">×</button> </div> </div> <style> #nl-whatsapp-float{position:fixed;bottom:24px;right:24px;width:60px;height:60px;background:#25D366;border-radius:50%;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px rgba(37,211,102,.4);z-index:9998;transition:transform .2s;text-decoration:none} #nl-whatsapp-float:hover{transform:scale(1.08)} #nl-whatsapp-float::after{content:"Habla con un experto";position:absolute;right:72px;top:50%;transform:translateY(-50%);background:#111;color:#fff;padding:6px 12px;border-radius:6px;font-size:13px;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .2s} #nl-whatsapp-float:hover::after{opacity:1} #nl-exit-popup{position:fixed;inset:0;background:rgba(10,15,30,.85);z-index:10000;display:none;align-items:center;justify-content:center;padding:20px} #nl-exit-popup.open{display:flex} .nl-exit-card{background:#fff;border-radius:16px;padding:40px 32px;max-width:460px;width:100%;box-shadow:0 20px 60px rgba(0,0,0,.3);position:relative;animation:nlPop .3s ease} @keyframes nlPop{from{transform:scale(.9);opacity:0}to{transform:scale(1);opacity:1}} .nl-exit-close{position:absolute;top:12px;right:16px;background:none;border:0;font-size:28px;cursor:pointer;color:#888;line-height:1} .nl-exit-badge{display:inline-block;background:#ff4757;color:#fff;padding:4px 12px;border-radius:20px;font-size:11px;font-weight:800;letter-spacing:1px;margin-bottom:12px} .nl-exit-card h3{margin:0 0 10px;font-size:24px;color:#0a0f1e;font-weight:800;line-height:1.2} .nl-exit-card p{color:#444;font-size:15px;line-height:1.5;margin:0 0 20px} .nl-exit-card p strong{color:#0a0f1e} #nl-exit-form input{width:100%;padding:14px 16px;border:1.5px solid #e5e7eb;border-radius:10px;font-size:15px;margin-bottom:10px;box-sizing:border-box;font-family:inherit} #nl-exit-form input:focus{outline:0;border-color:#0066ff} #nl-exit-form button{width:100%;padding:16px;background:linear-gradient(135deg,#0066ff,#00aaff);color:#fff;border:0;border-radius:10px;font-size:16px;font-weight:700;cursor:pointer;margin-top:6px;transition:transform .15s} #nl-exit-form button:hover{transform:translateY(-1px)} #nl-exit-form small{display:block;margin-top:10px;color:#888;font-size:12px;text-align:center} #nl-sticky-bar{position:fixed;bottom:0;left:0;right:0;background:linear-gradient(135deg,#0a0f1e,#1a2547);color:#fff;padding:14px 20px;display:none;align-items:center;justify-content:center;gap:16px;z-index:9997;flex-wrap:wrap;box-shadow:0 -4px 20px rgba(0,0,0,.2)} #nl-sticky-bar.open{display:flex} .nl-sticky-msg{font-size:14px} .nl-sticky-cta{background:#00e676;color:#0a0f1e;padding:8px 18px;border-radius:8px;font-weight:700;text-decoration:none;font-size:14px;transition:transform .15s} .nl-sticky-cta:hover{transform:translateY(-1px)} .nl-sticky-close{background:none;border:0;color:#fff;font-size:20px;cursor:pointer;opacity:.6} @media(max-width:640px){ #nl-whatsapp-float{bottom:90px;right:16px;width:54px;height:54px} #nl-whatsapp-float::after{display:none} .nl-exit-card{padding:28px 20px} .nl-exit-card h3{font-size:20px} #nl-sticky-bar{flex-direction:column;gap:8px;padding:12px 16px} } </style> <script> (function(){ window.NebuLab=window.NebuLab||{}; var shownExit=sessionStorage.getItem('nl_exit_shown'); var closedSticky=sessionStorage.getItem('nl_sticky_closed'); var popup=document.getElementById('nl-exit-popup'); var sticky=document.getElementById('nl-sticky-bar'); function openPopup(){if(shownExit)return;popup.classList.add('open');popup.setAttribute('aria-hidden','false');sessionStorage.setItem('nl_exit_shown','1');if(typeof gtag==='function')gtag('event','exit_popup_open',{event_category:'lead'});} function closePopup(){popup.classList.remove('open');popup.setAttribute('aria-hidden','true');} document.addEventListener('mouseout',function(e){if(!e.toElement&&!e.relatedTarget&&e.clientY<10)openPopup();}); setTimeout(function(){if(!shownExit)openPopup();},45000); if(popup){popup.querySelector('.nl-exit-close').addEventListener('click',closePopup);popup.addEventListener('click',function(e){if(e.target===popup)closePopup();});} if(sticky&&!closedSticky){setTimeout(function(){sticky.classList.add('open');},8000);sticky.querySelector('.nl-sticky-close').addEventListener('click',function(){sticky.classList.remove('open');sessionStorage.setItem('nl_sticky_closed','1');});} NebuLab.submitExit=function(e){e.preventDefault();var f=e.target,fd=new FormData(f);fd.append('source','exit_popup');fd.append('page',location.pathname);fetch('/wp-json/nebulab/v1/lead',{method:'POST',body:fd}).then(function(r){return r.json();}).then(function(d){f.innerHTML='<p style="text-align:center;color:#00aa55;font-weight:700;font-size:16px;padding:20px 0">✓ Listo. Revisa tu email — llega en 2 minutos.</p>';if(typeof gtag==='function')gtag('event','generate_lead',{event_category:'lead',event_label:'exit_popup'});setTimeout(closePopup,3000);});return false;}; NebuLab.track=function(name,data){if(typeof gtag==='function')gtag('event',name,data||{});}; })(); </script> <!-- NebuLab eventos de negocio --> <script> (function () { if (typeof gtag !== 'function') return; function ubicacion(el) { if (el.closest('header, .nl-header, nav')) return 'header'; if (el.closest('footer, .nl-footer')) return 'footer'; if (el.closest('.nl-hero, #hero')) return 'hero'; return 'cuerpo'; } document.addEventListener('click', function (e) { var a = e.target.closest('a'); if (!a) return; var href = (a.getAttribute('href') || '').toLowerCase(); if (!href) return; var evento = null; if (href.indexOf('wa.me') > -1 || href.indexOf('api.whatsapp.com') > -1 || href.indexOf('whatsapp://') > -1) { evento = 'clic_whatsapp'; } else if (href.indexOf('tel:') === 0) { evento = 'clic_telefono'; } else if (href.indexOf('mailto:') === 0) { evento = 'clic_email'; } else if (href.indexOf('calendly') > -1 || href.indexOf('cal.com') > -1) { evento = 'clic_agendar'; } if (!evento) return; gtag('event', evento, { pagina: location.pathname, ubicacion: ubicacion(a), destino: href.slice(0, 100) }); }, true); // Envío de formularios (Contact Form 7 y formularios nativos). document.addEventListener('wpcf7mailsent', function (e) { gtag('event', 'envio_formulario', { pagina: location.pathname, formulario: 'cf7_' + ((e.detail && e.detail.contactFormId) || 'sin_id') }); }, false); document.addEventListener('submit', function (e) { var f = e.target; if (!f || f.tagName !== 'FORM') return; if (f.classList.contains('wpcf7-form')) return; // ya lo cubre wpcf7mailsent if (f.closest('.wp-block-search, .search-form') || f.getAttribute('role') === 'search') return; gtag('event', 'envio_formulario', { pagina: location.pathname, formulario: f.getAttribute('id') || f.getAttribute('name') || 'form_nativo' }); }, true); // Scroll profundo: señal de interés real en páginas de servicio. var marcado = false; window.addEventListener('scroll', function () { if (marcado) return; var alto = document.body.scrollHeight - window.innerHeight; if (alto > 0 && (window.scrollY / alto) >= 0.75) { marcado = true; gtag('event', 'scroll_75', { pagina: location.pathname }); } }, { passive: true }); })(); </script> <!-- NebuLab · atribución --> <script> (function () { var REST = "https:\/\/nebu-lab.com\/wp-json\/nebulab\/v1\/atribucion"; var MARCA = "nebu-lab.com"; var FIRMA = '— Vengo de ' + MARCA; /* ---------- cookies de primera parte ---------- */ function galleta(n) { var m = document.cookie.match('(^|;)\\s*' + n + '\\s*=\\s*([^;]+)'); if (!m) return null; try { return JSON.parse(decodeURIComponent(m[2])); } catch (e) { return null; } } function guardar(n, v, dias) { try { var f = new Date(Date.now() + dias * 864e5).toUTCString(); document.cookie = n + '=' + encodeURIComponent(JSON.stringify(v)) + ';expires=' + f + ';path=/;SameSite=Lax' + (location.protocol === 'https:' ? ';Secure' : ''); } catch (e) {} } /* ---------- de dónde viene esta visita ---------- */ var IA = /(chatgpt\.com|chat\.openai|perplexity\.ai|copilot\.microsoft|gemini\.google|claude\.ai|you\.com|poe\.com|mistral\.ai|deepseek)/i; var BUSCADOR = /(google\.|bing\.|duckduckgo|yahoo\.|ecosia|brave\.com|yandex|search\.marginalia)/i; var SOCIAL = /(facebook|instagram|linkedin|t\.co|twitter|x\.com|tiktok|youtube|whatsapp|reddit|pinterest|threads)/i; var CAMPO_UTM = ['utm_source','utm_medium','utm_campaign','utm_term','utm_content']; var CAMPO_ID = ['gclid','gbraid','wbraid','fbclid','msclkid','ttclid','li_fat_id','twclid']; function param(n) { try { return new URLSearchParams(location.search).get(n) || ''; } catch (e) { return ''; } } function leerVisita() { var utm = {}, i, v; for (i = 0; i < CAMPO_UTM.length; i++) { v = param(CAMPO_UTM[i]); if (v) utm[CAMPO_UTM[i]] = v; } for (i = 0; i < CAMPO_ID.length; i++) { v = param(CAMPO_ID[i]); if (v) utm[CAMPO_ID[i]] = v; } var host = ''; try { host = document.referrer ? new URL(document.referrer).hostname : ''; } catch (e) {} if (host && host.replace(/^www\./, '') === location.hostname.replace(/^www\./, '')) host = ''; var canal; if (utm.gclid || utm.gbraid || utm.wbraid) canal = 'google_ads'; else if (utm.msclkid) canal = 'microsoft_ads'; else if (utm.fbclid) canal = 'meta_ads'; else if (utm.ttclid) canal = 'tiktok_ads'; else if (utm.utm_medium) canal = utm.utm_medium; else if (IA.test(host)) canal = 'ia'; else if (BUSCADOR.test(host)) canal = 'organico'; else if (SOCIAL.test(host)) canal = 'social'; else if (host) canal = 'referencia'; else canal = 'directo'; return { canal: canal, host: host, utm: utm, landing: location.pathname, ref_web: document.referrer || '', t: new Date().toISOString().slice(0, 16).replace('T', ' ') }; } function resumen(v) { if (!v) return ''; var p = [v.canal]; if (v.host) p.push(v.host); if (v.utm && v.utm.utm_campaign) p.push('camp: ' + v.utm.utm_campaign); if (v.utm && v.utm.utm_source && v.utm.utm_source !== v.host) p.push('src: ' + v.utm.utm_source); p.push(v.landing || '/'); p.push(v.t || ''); return p.join(' · '); } var visita = leerVisita(); var senal = !!(visita.host || Object.keys(visita.utm).length); var primero = galleta('nl_ft'); if (!primero) { primero = visita; guardar('nl_ft', primero, 180); } var ultimo = galleta('nl_lt'); if (!ultimo || senal) { ultimo = visita; guardar('nl_lt', ultimo, 90); } // Cuántas veces ha entrado antes de dar el paso: mide el peso del contenido. var cuenta = (galleta('nl_n') || 0); if (typeof cuenta !== 'number') cuenta = 0; if (!sessionStorage.getItem('nl_visto')) { cuenta++; guardar('nl_n', cuenta, 180); try { sessionStorage.setItem('nl_visto', '1'); } catch (e) {} } /* ---------- código de referencia ---------- */ function nuevoRef() { var a = Date.now().toString(36).toUpperCase().slice(-5); var b = Math.random().toString(36).toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 3); return 'NL-' + a + b; } function gaCid() { var m = document.cookie.match(/_ga=GA\d\.\d\.(\d+\.\d+)/); return m ? m[1] : ''; } function registrar(extra) { var d = { pagina: location.href, canal: ultimo.canal, origen: resumen(ultimo), primero: resumen(primero), landing: primero.landing || '/', ref_web: ultimo.ref_web || '', utm: ultimo.utm || {}, ga_cid: gaCid(), visitas: cuenta, disp: (window.matchMedia && window.matchMedia('(max-width:768px)').matches) ? 'movil' : 'escritorio' }; for (var k in extra) if (Object.prototype.hasOwnProperty.call(extra, k)) d[k] = extra[k]; var cuerpo = JSON.stringify(d); try { if (navigator.sendBeacon && navigator.sendBeacon(REST, new Blob([cuerpo], { type: 'application/json' }))) return; } catch (e) {} try { fetch(REST, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: cuerpo, keepalive: true }).catch(function () {}); } catch (e) {} } /* ---------- GA4: NO se manda ningún evento nuevo ---------- `nebulab-medicion.php` ya dispara clic_whatsapp / clic_telefono / clic_email / envio_formulario. Mandar otro evento por el mismo clic sería contar dos veces la misma conversión — el error que infló las cuentas de otros clientes. Así que en vez de añadir eventos, se le cuelgan los datos de origen a los que ya existen. */ var refActual = ''; (function envolverGtag() { var previo = window.gtag; if (typeof previo !== 'function') return; window.gtag = function () { var a = Array.prototype.slice.call(arguments); try { if (a[0] === 'event' && typeof a[1] === 'string' && /^(clic_|envio_formulario|generate_lead)/.test(a[1])) { var d = (a[2] && typeof a[2] === 'object') ? a[2] : {}; var extra = { id_referencia: refActual, canal_origen: ultimo.canal, canal_primero: (primero && primero.canal) || '', campana: (ultimo.utm && ultimo.utm.utm_campaign) || '', web_origen: ultimo.host || 'directo', visitas_previas: cuenta }; for (var k in extra) if (!(k in d)) d[k] = extra[k]; a[2] = d; } } catch (e) {} return previo.apply(this, a); }; })(); /* ---------- marcar el enlace de WhatsApp ---------- */ function marcarWa(a, ref) { var href = a.getAttribute('href') || ''; try { var u = new URL(href, location.origin); var txt = u.searchParams.get('text') || ''; // Quita cualquier firma anterior —la estática del servidor, que llega con «·» // desde el tema y con salto de línea desde el mu-plugin, o la de un clic previo— // para que el mensaje no se llene de líneas repetidas. var corte = txt.indexOf('Vengo de ' + MARCA); if (corte > -1) txt = txt.slice(0, corte).replace(/[\s·—-]+$/, ''); txt += '\n\n' + FIRMA + location.pathname + ' · ref ' + ref; u.searchParams.set('text', txt); a.setAttribute('href', u.toString()); } catch (e) {} } /* ---------- clics que valen dinero ---------- Va en `window` y en fase de captura a propósito: así corre ANTES que el listener de nebulab-medicion.php (que está en `document`) y el código de referencia ya existe cuando ese dispara su evento de GA4. */ window.addEventListener('click', function (e) { var a = e.target && e.target.closest ? e.target.closest('a') : null; if (!a) return; var href = (a.getAttribute('href') || '').toLowerCase(); if (!href) return; var accion = null; if (href.indexOf('wa.me') > -1 || href.indexOf('api.whatsapp.com') > -1 || href.indexOf('whatsapp://') > -1) accion = 'whatsapp'; else if (href.indexOf('tel:') === 0) accion = 'telefono'; else if (href.indexOf('mailto:') === 0) accion = 'email'; else if (href.indexOf('calendly') > -1 || href.indexOf('cal.com') > -1) accion = 'agendar'; if (!accion) return; refActual = nuevoRef(); if (accion === 'whatsapp') marcarWa(a, refActual); registrar({ tipo: 'clic', accion: accion, ref: refActual }); }, true); /* ---------- formularios: sembrar el origen dentro ---------- */ function esBuscador(f) { return !!(f.closest('.wp-block-search, .search-form') || f.getAttribute('role') === 'search' || f.querySelector('input[type=search]')); } function campo(f, n, v) { if (f.querySelector('input[name="' + n + '"]')) { f.querySelector('input[name="' + n + '"]').value = v; return; } var i = document.createElement('input'); i.type = 'hidden'; i.name = n; i.value = v; f.appendChild(i); } function sembrar() { var fs = document.querySelectorAll('form'); for (var i = 0; i < fs.length; i++) { var f = fs[i]; if (f.getAttribute('data-nl-atr') || esBuscador(f)) continue; f.setAttribute('data-nl-atr', nuevoRef()); campo(f, 'nl_ref', f.getAttribute('data-nl-atr')); campo(f, 'nl_canal', ultimo.canal); campo(f, 'nl_origen', resumen(ultimo)); campo(f, 'nl_primero', resumen(primero)); campo(f, 'nl_landing', primero.landing || '/'); campo(f, 'nl_pagina', location.href); campo(f, 'nl_visitas', String(cuenta)); } } sembrar(); if (window.MutationObserver) { new MutationObserver(sembrar).observe(document.documentElement, { childList: true, subtree: true }); } function enviado(f) { if (!f || f.tagName !== 'FORM' || esBuscador(f)) return; refActual = f.getAttribute('data-nl-atr') || nuevoRef(); var e = f.querySelector('input[type=email], input[name*=mail], input[name*=correo]'); registrar({ tipo: 'lead', accion: 'formulario', ref: refActual, email: e ? e.value : '' }); } window.addEventListener('submit', function (e) { enviado(e.target); }, true); document.addEventListener('wpcf7mailsent', function (e) { enviado(e.target && e.target.tagName === 'FORM' ? e.target : (e.target ? e.target.querySelector('form') : null)); }, false); })(); </script> <!-- NebuLab · puerta de WhatsApp --> <style> #nl-pta{position:fixed;inset:0;z-index:99999;display:none} #nl-pta[data-abierto]{display:block} #nl-pta .nl-pta-fondo{position:absolute;inset:0;background:rgba(18,18,26,.55);backdrop-filter:blur(2px);animation:nlPtaFade .18s ease} #nl-pta .nl-pta-caja{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:min(420px,calc(100vw - 32px)); background:var(--nl-surface,#fff);color:var(--nl-ink,#12121A);border-radius:var(--nl-r-card,16px); padding:28px 26px 22px;box-shadow:0 24px 60px -20px rgba(18,18,26,.45); font-family:var(--font-sans,'Inter',system-ui,sans-serif);animation:nlPtaIn .2s cubic-bezier(.2,.8,.2,1); max-height:calc(100dvh - 32px);overflow:auto} @keyframes nlPtaFade{from{opacity:0}to{opacity:1}} @keyframes nlPtaIn{from{opacity:0;transform:translate(-50%,-46%)}to{opacity:1;transform:translate(-50%,-50%)}} #nl-pta .nl-pta-x{position:absolute;top:10px;right:12px;width:36px;height:36px;border:0;background:transparent; color:var(--nl-mute,#7A7A88);font-size:26px;line-height:1;cursor:pointer;border-radius:50%} #nl-pta .nl-pta-x:hover{background:var(--nl-canvas-2,#F1EFE9);color:var(--nl-ink,#12121A)} #nl-pta .nl-pta-ico{width:44px;height:44px;border-radius:12px;background:var(--nl-signal-tint,#E6F7EF); display:grid;place-items:center;margin-bottom:14px} #nl-pta h2{font-family:var(--font-display,Georgia,serif);font-size:23px;line-height:1.2;margin:0 0 6px;font-weight:500} #nl-pta .nl-pta-sub{font-size:14.5px;line-height:1.5;color:var(--nl-ink-mute,#4A4A57);margin:0 0 18px} #nl-pta label{display:block;font-size:13px;font-weight:600;margin:0 0 6px;color:var(--nl-ink-soft,#23232E)} #nl-pta input[type=text],#nl-pta input[type=tel]{width:100%;box-sizing:border-box;padding:12px 14px;font-size:16px; font-family:inherit;color:var(--nl-ink,#12121A);background:var(--nl-canvas,#F9F8F4); border:1px solid var(--nl-line,#E3E0D9);border-radius:var(--nl-r-input,10px);margin:0 0 14px;-webkit-appearance:none} #nl-pta input:focus{outline:2px solid var(--nl-accent,#5B3DF5);outline-offset:1px;background:#fff} #nl-pta input[aria-invalid=true]{border-color:#D92D20;background:#FEF3F2} #nl-pta .nl-pta-trampa{position:absolute!important;left:-9999px!important;width:1px!important;height:1px!important;opacity:0!important} #nl-pta .nl-pta-err{margin:-6px 0 12px;font-size:13px;color:#B42318;font-weight:500} #nl-pta button[type=submit]{width:100%;padding:14px 18px;font-size:16px;font-weight:600;font-family:inherit; color:#fff;background:#25D366;border:0;border-radius:var(--nl-r-pill,999px);cursor:pointer; display:flex;align-items:center;justify-content:center;gap:9px;transition:filter .15s,transform .15s} #nl-pta button[type=submit]:hover:not(:disabled){filter:brightness(.94);transform:translateY(-1px)} #nl-pta button[type=submit]:disabled{opacity:.65;cursor:progress} #nl-pta .nl-pta-legal{font-size:11.5px;line-height:1.5;color:var(--nl-mute,#7A7A88);margin:12px 0 0;text-align:center} #nl-pta .nl-pta-legal a{color:inherit;text-decoration:underline} @media (max-width:520px){ #nl-pta .nl-pta-caja{top:auto;bottom:0;left:0;transform:none;width:100%;max-width:none; border-radius:20px 20px 0 0;padding:24px 20px calc(20px + env(safe-area-inset-bottom));animation:nlPtaUp .22s cubic-bezier(.2,.8,.2,1)} @keyframes nlPtaUp{from{transform:translateY(100%)}to{transform:translateY(0)}} } @media (prefers-reduced-motion:reduce){#nl-pta *{animation:none!important;transition:none!important}} </style> <div id="nl-pta" aria-hidden="true"> <div class="nl-pta-fondo" data-nl-cerrar></div> <div class="nl-pta-caja" role="dialog" aria-modal="true" aria-labelledby="nl-pta-tit"> <button type="button" class="nl-pta-x" data-nl-cerrar aria-label="Cerrar">×</button> <div class="nl-pta-ico" aria-hidden="true"> <svg width="24" height="24" viewBox="0 0 24 24" fill="#17B26A"><path d="M20.5 3.5A11.9 11.9 0 0 0 12 0C5.5 0 .2 5.3.2 11.8c0 2.1.6 4.1 1.6 5.9L0 24l6.4-1.7a11.8 11.8 0 0 0 5.6 1.4c6.5 0 11.8-5.3 11.8-11.8 0-3.2-1.2-6.1-3.3-8.4zM12 21.5c-1.8 0-3.5-.5-5-1.4l-.4-.2-3.8 1 1-3.7-.2-.4a9.7 9.7 0 0 1-1.5-5.2c0-5.4 4.4-9.8 9.9-9.8 2.6 0 5.1 1 6.9 2.9a9.7 9.7 0 0 1 2.9 6.9c0 5.4-4.4 9.9-9.8 9.9z"/></svg> </div> <h2 id="nl-pta-tit">Te abrimos el chat</h2> <p class="nl-pta-sub">Déjanos dos datos y seguimos por WhatsApp. Si se te corta la conversación, te escribimos nosotros.</p> <form id="nl-pta-form" novalidate> <label for="nl-pta-nombre">Tu nombre</label> <input id="nl-pta-nombre" name="nombre" type="text" autocomplete="name" maxlength="80" placeholder="Ana Pérez" required> <label for="nl-pta-tel">Tu teléfono</label> <input id="nl-pta-tel" name="telefono" type="tel" inputmode="tel" autocomplete="tel" maxlength="30" placeholder="55 1234 5678" required> <p class="nl-pta-err" role="alert" hidden></p> <button type="submit"> <svg width="19" height="19" viewBox="0 0 24 24" fill="#fff" aria-hidden="true"><path d="M20.5 3.5A11.9 11.9 0 0 0 12 0C5.5 0 .2 5.3.2 11.8c0 2.1.6 4.1 1.6 5.9L0 24l6.4-1.7a11.8 11.8 0 0 0 5.6 1.4c6.5 0 11.8-5.3 11.8-11.8 0-3.2-1.2-6.1-3.3-8.4z"/></svg> <span data-nl-texto>Abrir WhatsApp</span> </button> <p class="nl-pta-legal">Solo usamos tus datos para atender tu consulta. <a href="https://nebu-lab.com/politica-de-privacidad/" target="_blank" rel="noopener">Política de privacidad</a>.</p> </form> </div> </div> <script> (function () { var REST = "https:\/\/nebu-lab.com\/wp-json\/nebulab\/v1\/puerta", REST2 = "https:\/\/nebu-lab.com\/wp-json\/nebulab\/v1\/puerta-abierta"; var caja = document.getElementById('nl-pta'); if (!caja) return; var form = document.getElementById('nl-pta-form'); var iNom = document.getElementById('nl-pta-nombre'); var iTel = document.getElementById('nl-pta-tel'); var pErr = caja.querySelector('.nl-pta-err'); var btn = form.querySelector('button[type=submit]'); var txtB = form.querySelector('[data-nl-texto]'); var abierta = 0, mensajeBase = '', devuelve = null, enviando = false; // Campo trampa: lo añade el JS y va oculto por CSS con type=text (los bots ignoran los hidden). var trampa = document.createElement('input'); trampa.type = 'text'; trampa.name = 'nl_sitio_web'; trampa.className = 'nl-pta-trampa'; trampa.tabIndex = -1; trampa.setAttribute('autocomplete', 'off'); trampa.setAttribute('aria-hidden', 'true'); form.insertBefore(trampa, form.firstChild); var token = Math.random().toString(36).slice(2) + Date.now().toString(36); function esWa(href) { href = (href || '').toLowerCase(); return href.indexOf('wa.me') > -1 || href.indexOf('api.whatsapp.com') > -1 || href.indexOf('whatsapp://') > -1; } function textoDe(href) { try { return new URL(href, location.origin).searchParams.get('text') || ''; } catch (e) { return ''; } } function abrir(base, origen) { mensajeBase = base || ''; devuelve = origen || null; abierta = Date.now(); caja.setAttribute('data-abierto', '1'); caja.setAttribute('aria-hidden', 'false'); document.documentElement.style.overflow = 'hidden'; pErr.hidden = true; iNom.removeAttribute('aria-invalid'); iTel.removeAttribute('aria-invalid'); setTimeout(function () { iNom.focus(); }, 60); } function cerrar() { caja.removeAttribute('data-abierto'); caja.setAttribute('aria-hidden', 'true'); document.documentElement.style.overflow = ''; if (devuelve && devuelve.focus) { try { devuelve.focus(); } catch (e) {} } } caja.addEventListener('click', function (e) { if (e.target.hasAttribute('data-nl-cerrar')) cerrar(); }); document.addEventListener('keydown', function (e) { if (!caja.hasAttribute('data-abierto')) return; if (e.key === 'Escape') { cerrar(); return; } if (e.key !== 'Tab') return; // Encerrar el tabulador dentro del diálogo. var f = caja.querySelectorAll('button, input:not(.nl-pta-trampa), a[href]'); if (!f.length) return; var p = f[0], u = f[f.length - 1]; if (e.shiftKey && document.activeElement === p) { e.preventDefault(); u.focus(); } else if (!e.shiftKey && document.activeElement === u) { e.preventDefault(); p.focus(); } }); /* Intercepta TODO enlace de WhatsApp, venga del tema, del botón flotante o de un shortcode. Va en fase de burbuja a propósito: así el listener de atribución (que está en captura) ya ha corrido, el clic queda medido y el enlace ya lleva su código de referencia. */ document.addEventListener('click', function (e) { var a = e.target && e.target.closest ? e.target.closest('a') : null; if (!a || !esWa(a.getAttribute('href'))) return; if (a.hasAttribute('data-nl-sin-puerta')) return; e.preventDefault(); e.stopPropagation(); abrir(textoDe(a.getAttribute('href')), a); }, false); /* El enlace pulsado ya podía traer la firma que pone nebulab-atribucion.php. Se quita antes de rearmar el mensaje, o salen dos firmas con dos códigos distintos. */ function limpiaFirma(t) { t = t || ''; var i = t.indexOf('Vengo de nebu-lab.com'); if (i > -1) t = t.slice(0, i).replace(/[\s·—-]+$/, ''); return t.trim(); } /* Mismas reglas que nl_puerta_e164() en PHP, para que el mensaje salga ya normalizado. */ function aE164(tel) { var d = String(tel).replace(/\D/g, ''); if (d.indexOf('00') === 0) d = d.slice(2); var l = d.length; if (l === 10) return '+52' + d; if (l === 12 && d.indexOf('52') === 0) return '+' + d; if (l === 13 && d.indexOf('521') === 0) return '+52' + d.slice(3); if (l === 11 && d.indexOf('1') === 0) return '+' + d; if (l >= 8 && l <= 15) return '+' + d; return tel; } function campo(n) { var i = form.querySelector('[name="' + n + '"]'); return i ? i.value : ''; } function galleta(n) { var m = document.cookie.match('(^|;)\\s*' + n + '\\s*=\\s*([^;]+)'); if (!m) return null; try { return JSON.parse(decodeURIComponent(m[2])); } catch (e) { return null; } } function gaCid() { var m = document.cookie.match(/_ga=GA\d\.\d\.(\d+\.\d+)/); return m ? m[1] : ''; } form.addEventListener('submit', function (e) { e.preventDefault(); if (enviando) return; var nombre = iNom.value.trim(), tel = iTel.value.trim(); var digitos = tel.replace(/\D/g, ''); iNom.removeAttribute('aria-invalid'); iTel.removeAttribute('aria-invalid'); if (nombre.length < 2) { pErr.textContent = 'Dinos cómo te llamas.'; pErr.hidden = false; iNom.setAttribute('aria-invalid', 'true'); iNom.focus(); return; } if (digitos.length < 10) { pErr.textContent = 'El teléfono necesita 10 dígitos.'; pErr.hidden = false; iTel.setAttribute('aria-invalid', 'true'); iTel.focus(); return; } pErr.hidden = true; var ultimo = galleta('nl_lt') || {}, primero = galleta('nl_ft') || {}, visitas = galleta('nl_n') || 0; var datos = { nombre: nombre, telefono: tel, mensaje: mensajeBase, ref: form.getAttribute('data-nl-atr') || campo('nl_ref') || '', canal: (ultimo.canal || campo('nl_canal') || ''), canal_primero: (primero.canal || ''), campana: ((ultimo.utm || {}).utm_campaign || ''), web_origen: (ultimo.host || ''), landing: (primero.landing || campo('nl_landing') || ''), pagina: location.href, utm: (ultimo.utm || {}), ga_cid: gaCid(), dispositivo: (window.matchMedia && window.matchMedia('(max-width:768px)').matches) ? 'movil' : 'escritorio', visitas: (typeof visitas === 'number' ? visitas : 0), nl_sitio_web: trampa.value, token: token, segundos: abierta ? (Date.now() - abierta) / 1000 : 99 }; // El mensaje definitivo se arma AQUÍ, entero. Antes se abría uno provisional y se // intentaba reemplazar la URL de la ventana ya abierta: eso deja el teléfono sin // normalizar y depende de un permiso entre ventanas de distinto dominio. var texto = limpiaFirma(mensajeBase) || "\u00a1Hola! Necesito ayuda con un proyecto de SEO. \u00bfMe podr\u00edan contactar para explicarles en detalle? Gracias."; texto += '\n\nNombre: ' + nombre + '\nTeléfono: ' + aE164(tel); texto += '\n\n— Vengo de nebu-lab.com' + location.pathname + (datos.ref ? ' · ref ' + datos.ref : ''); var url = 'https://wa.me/5215532007498?text=' + encodeURIComponent(texto); // La ventana se abre dentro del gesto del usuario: si se abriera dentro del .then() // del fetch, el navegador lo tomaría por emergente y la bloquearía. var ventana = window.open(url, '_blank'); if (!ventana) { location.href = url; } enviando = true; btn.disabled = true; txtB.textContent = 'Abriendo…'; fetch(REST, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(datos), keepalive: true }) .then(function (r) { return r.json(); }) .then(function (j) { if (j && j.id) { try { navigator.sendBeacon(REST2, new Blob([JSON.stringify({ id: j.id })], { type: 'application/json' })); } catch (e) {} } }) .catch(function () {}) .finally(function () { enviando = false; btn.disabled = false; txtB.textContent = 'Abrir WhatsApp'; cerrar(); }); }); })(); </script> </body> </html>