Saltar al contenido principal

Captive Portal personalizado: guía de HTML y CSS

Esta guía de referencia técnica autorizada describe los estándares de desarrollo, la arquitectura CSS y las limitaciones a nivel de red necesarias para diseñar y programar una página de inicio de Captive Portal personalizada. Proporciona a los desarrolladores frontend y arquitectos de red estrategias prácticas para navegar por los entornos Apple CNA y Android webview, garantizando experiencias de WiFi para invitados perfectas al píxel, conformes y de alto rendimiento.

📖 11 min de lectura📝 2,731 palabras🔧 2 ejemplos prácticos3 preguntas de práctica📚 8 definiciones clave

Escuchar esta guía

Ver transcripción del podcast
Captive Portal personalizado: guía de HTML y CSS — Una sesión informativa técnica de Purple [INTRODUCTION] Le damos la bienvenida a la serie de sesiones informativas técnicas de Purple. Hoy vamos a profundizar en algo que afecta a todas las implementaciones de WiFi para invitados: el Captive Portal. En concreto, hablaremos de cómo escribir HTML y CSS limpios y fiables para una página de inicio de Captive Portal personalizada. Si alguna vez se ha conectado al WiFi de un hotel y se ha encontrado con una página de bienvenida rota (imágenes que faltan, texto sin estilo, un botón de inicio de sesión que no responde al tacto), habrá experimentado lo que ocurre cuando un desarrollador crea un portal sin comprender las limitaciones del entorno en el que se ejecuta. Hoy nos aseguraremos de que eso no le ocurra a usted. Esta sesión informativa está dirigida a desarrolladores frontend, diseñadores creativos y desarrolladores web que estén creando un Captive Portal desde cero o personalizando una plantilla existente. Cubriremos la estructura HTML, las reglas CSS más importantes, las limitaciones del mini-navegador Apple CNA que confunden incluso a desarrolladores experimentados y cómo las plataformas como el creador de portales de Purple pueden eliminar por completo la mayor parte de esta complejidad. Comencemos. [TECHNICAL DEEP-DIVE] En primer lugar, establezcamos qué es realmente un Captive Portal a nivel de red. Cuando un dispositivo se conecta a una red WiFi que requiere autenticación, la red intercepta el tráfico HTTP y redirige al usuario a una página de inicio. Este es el Captive Portal. El usuario ve una página de bienvenida, completa una acción (introducir un correo electrónico, aceptar las condiciones, iniciar sesión a través de redes sociales) y la red le concede acceso completo a Internet. Lo fundamental es entender dónde se renderiza esta página. En los dispositivos iOS, se abre dentro del Captive Network Assistant de Apple (el CNA), que es una vista web de WebKit simplificada. No es Safari. No tiene cookies persistentes. No puede cargar recursos externos. Tiene soporte limitado para JavaScript. And it closes the moment the user switches to another app. En macOS, el CNA se renderiza a un tamaño fijo de 900 por 572 píxeles. En Android, los dispositivos modernos utilizan Chrome Custom Tabs, que son considerablemente más potentes. Windows 10 abre el navegador predeterminado del usuario. Los dispositivos Samsung utilizan Samsung Internet. Esta fragmentación de plataformas es la mayor fuente de fallos en los Captive Portals en producción. Los desarrolladores realizan pruebas en su teléfono Android, todo se ve genial y luego los invitados del hotel que usan iPhone se encuentran con una pantalla blanca con texto sin estilo. Hablemos, pues, de cómo programar de forma defensiva. La regla de oro para el HTML y CSS de un Captive Portal es esta: trate la página como si no tuviera conexión a Internet. Porque durante la fase de autenticación, no la tiene. La red es cautiva. Cualquier recurso que su página intente cargar desde una URL externa (una fuente de Google Fonts, una hoja de estilo alojada en una CDN, una biblioteca de JavaScript, una imagen de logotipo) fallará silenciosamente o provocará un indicador de carga que nunca se resolverá. Comenzando con la estructura HTML. Su documento debe ser una página HTML5 limpia. En la cabecera, necesita una etiqueta meta viewport con el contenido establecido en width igual a device-width e initial-scale igual a uno. Esto no es negociable para el renderizado móvil. Sin ella, iOS renderizará la página a 980 píxeles de ancho y reducirá su escala, haciendo que todo se vea microscópico. Su CSS must be inline — ya sea en un bloque de estilo dentro del elemento head o como atributos de estilo en línea en elementos individuales. No utilice una hoja de estilo externa enlazada mediante una etiqueta link. Esa hoja de estilo reside en su servidor, al que la red cautiva no puede acceder durante la autenticación. La página se renderizará completamente sin estilo. Para las fuentes, utilice una pila de fuentes del sistema. Algo como: font-family — apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif. Esto le indica al navegador que utilice cualquier fuente del sistema que esté disponible. No utilice Google Fonts. La llamada de importación fallará y su fuente de respaldo será Times New Roman, que no es la experiencia de marca por la que su cliente está pagando. Para las imágenes (su logotipo, gráficos de fondo, elementos decorativos), tiene dos opciones. O bien las sirve desde el mismo servidor del Captive Portal, lo que significa que están en la misma red local y son accesibles antes de que se complete la autenticación. O, mejor aún, codifíquelas como URI de datos Base64 directamente en su HTML o CSS. Esto elimina por completo la dependencia externa. Hablemos ahora del diseño de la página. Dado que más del noventa por ciento de los inicios de sesión en Captive Portals se realizan en dispositivos móviles, su diseño debe ser prioritario para móviles. Eso significa un diseño de una sola columna, con un ancho máximo de unos 480 píxeles, centrado en la página. Utilice flexbox en el elemento body: display flex, flex-direction column, align-items centre, justify-content centre, min-height 100 viewport height. Esto centra su tarjeta de contenido vertical y horizontalmente en cualquier tamaño de pantalla. Su botón de llamada a la acción principal debe ser fácil de tocar. Las Directrices de interfaz humana de Apple especifican un objetivo de toque mínimo de 44 por 44 píxeles. En la práctica, para una llamada a la acción principal, querrá algo más parecido a 48 píxeles de alto, de ancho completo dentro del contenedor, con un radio de borde de unos 8 a 12 píxeles. Para los campos de formulario (entrada de correo electrónico, entrada de nombre), establezca el tamaño de fuente en al menos 16 píxeles. Esto es fundamental. Safari en iOS y el CNA ampliarán automáticamente cualquier campo de entrada con un tamaño de fuente inferior a 16 píxeles, lo que romperá su diseño cuidadosamente elaborado. Establecer el tamaño de fuente en 16 píxeles o más evita este comportamiento de zoom. La sección de consentimiento legal merece especial atención. Según el GDPR, si recopila datos personales (incluso solo una dirección de correo electrónico), necesita un consentimiento explícito e informado. Esto significa una casilla de verificación desmarcada por defecto, con una etiqueta visible que indique claramente a qué está dando su consentimiento el usuario. No marque previamente la casilla de verificación. La propia casilla de consentimiento debe ser claramente visible sin necesidad de desplazarse. Ahora, un detalle de implementación crítico para el CNA de iOS específicamente. Cuando el usuario completa la autenticación, el CNA supervisa si el dominio cautivo ha pasado a ser accesible. La comprobación se activa mediante la navegación por la página completa, no por llamadas AJAX de JavaScript. Esto significa que si crea una aplicación de una sola página que envía el formulario a través de fetch o XMLHttpRequest y updates the DOM sin una redirección de página completa, el CNA nunca detectará que la autenticación se ha completado. Debe redirigir a una nueva URL después de la autenticación: una redirección HTTP completa, no una manipulación del DOM de JavaScript. Este es uno de los errores más comunes en el desarrollo de Captive Portals. Para JavaScript, manténgalo al mínimo. El CNA tiene un soporte de JS limitado y no tiene acceso a localStorage o sessionStorage. Las cookies se destruyen cuando se cierra el CNA. Cualquier gestión de estado que dependa de estas API del navegador fallará. Los escuchadores de eventos de JavaScript nativo están bien. jQuery es una dependencia externa de 30 kilobytes que no se cargará. [IMPLEMENTATION RECOMMENDATIONS AND PITFALLS] Permítame ofrecerle la lista de comprobación práctica para la implementación. Primero: etiqueta meta viewport, siempre. Segundo: todo el CSS en línea, sin hojas de estilo externas. Tercero: todas las imágenes servidas desde el servidor del Captive Portal o codificadas en Base64. Cuarto: pila de fuentes del sistema, sin fuentes web. Quinto: tamaño de fuente mínimo de 16 píxeles en todos los campos de entrada. Sexto: objetivos de toque fáciles de usar, mínimo de 44 por 44 píxeles. Séptimo: diseño de una sola columna, ancho máximo de 480 píxeles. Octavo: redirección de página completa al autenticarse, no una actualización de estado de JavaScript. Noveno: casilla de consentimiento conforme al GDPR, desmarcada por defecto. Décimo: realice pruebas en un dispositivo iOS real utilizando una red cautiva real, no una vista previa del navegador. Los errores que veo con más frecuencia en producción. Número uno: Google Fonts (elimine la importación, fallará). Número dos: bibliotecas de JavaScript externas (Bootstrap, jQuery, cualquier script alojado en CDN fallará). Número tres: variables CSS declaradas en una hoja de estilo externa (deben estar en su bloque de estilo en línea). Número cuatro: imágenes de fondo referenciadas por URL (codifíquelas en Base64). Número cinco: envío de formularios por AJAX sin una redirección posterior a la autenticación (el CNA no detectará la finalización de la autenticación). Ahora, la conversación honesta sobre desarrollar frente a comprar. Desarrollar un Captive Portal personalizado desde cero significa que usted también es responsable de la infraestructura de backend: el servidor RADIUS, la base de datos, el certificado SSL, la configuración de DNS, la integración de red con sus puntos de acceso y los parches de seguridad continuos. Se trata de un compromiso de ingeniería significativo. El creador de portales de Purple le ofrece una interfaz de arrastrar y soltar con un editor de HTML y CSS personalizado para los desarrolladores que necesitan un control perfecto al píxel, al tiempo que gestiona toda la infraestructura de backend: la autenticación, la captura de datos, los análisis, las herramientas de cumplimiento del GDPR y las integraciones de red con más de 200 proveedores de puntos de acceso. Obtiene el control creativo sin la sobrecarga de la infraestructura. [RAPID-FIRE Q AND A] ¿Puedo usar CSS Grid en un Captive Portal? Sí, pero pruébelo específicamente en el CNA de iOS. Flexbox tiene un soporte más amplio en versiones anteriores de WebKit. ¿Puedo usar logotipos SVG? Sí, los SVG en línea son totalmente compatibles y preferibles a los PNG codificados en Base64 para los logotipos porque se adaptan perfectamente a las pantallas retina. ¿El CNA de macOS admite las mismas limitaciones que el CNA de iOS? En general sí, con una diferencia: el CNA de macOS se renderiza en una ventana fija de 900 por 572 píxeles. ¿Puedo usar un framework CSS como Tailwind? Solo si genera un archivo CSS purgado y autónomo y lo incluye en su bloque de estilo. ¿Qué pasa con HTTPS? Su Captive Portal debe servirse a través de HTTP para que funcione la redirección inicial; las conexiones HTTPS no pueden ser interceptadas por la red cautiva. [SUMMARY AND NEXT STEPS] Para resumir la sesión informativa de hoy. Un Captive Portal personalizado es un entorno web restringido, no un contexto de navegador estándar. El CNA de Apple y las vistas web de Android imponen limitaciones estrictas a los recursos externos, las cookies, el JavaScript y el estado de la sesión. La solución consiste en crear páginas HTML autónomas con CSS en línea, fuentes del sistema, imágenes codificadas en Base64 y redirecciones de página completa al autenticarse. Para los operadores de recintos y los equipos de TI que evalúan sus opciones: si su requisito es un portal totalmente personalizado con HTML y CSS a medida, la elección está entre desarrollar y mantener toda la pila usted mismo (lo que supone un compromiso de ingeniería sustancial) o utilizar una plataforma como Purple que proporciona la capacidad de edición de HTML y CSS personalizados sobre una infraestructura de backend de nivel de producción. Los siguientes pasos a partir de aquí: revise la documentación del editor de portales de Purple, audite su portal existente con la lista de comprobación optimizada para móviles que hemos cubierto hoy y, si empieza desde cero, utilice la estructura de plantilla HTML que hemos descrito como base. Gracias por escuchar y nos vemos en la próxima sesión informativa.

📚 Parte de nuestra serie principal: La guía definitiva de Captive Portals

header_image.png

Executive Summary

For enterprise venues—ranging from luxury hotels Hospitality and retail chains Retail to transit hubs Transport and modern medical campuses Healthcare —the guest WiFi splash page is the digital front door. However, over 90% of guest WiFi logins occur on mobile devices, where rendering is governed not by standard browsers like Safari or Chrome, but by highly restricted Captive Network Assistant (CNA) webviews [1]. These "mini-browsers" enforce severe sandbox limitations: they block external CDNs, disable persistent cookies, ignore external web fonts, and severely restrict JavaScript execution to mitigate security risks and prevent session hijacking [2].

When a developer designs a splash page using traditional web standards, these constraints result in broken layouts, missing brand assets, and non-functional login buttons, directly impacting customer satisfaction and digital engagement. This guide provides solutions to these challenges, presenting defensive coding practices—such as inline CSS, Base64 asset encoding, system font stacks, and explicit navigation-driven authentication handshakes—to ensure seamless cross-platform rendering. Furthermore, we examine how utilising a managed solution like Purple's portal builder allows developers to maintain complete HTML/CSS creative control while offloading RADIUS authentication, database scaling, GDPR/PCI compliance, and multi-vendor AP integrations [3].

Technical Deep-Dive

To build a resilient custom captive portal, developers must understand the network-level interception and browser virtualisation that occurs when a guest associates with an open Service Set Identifier (SSID).

The Captive Portal Lifecycle

When a client device associates with a captive SSID, the following sequence is triggered:

  1. IP Association: The device completes a 3-way handshake and requests an IP address via DHCP.
  2. Active Connectivity Probe: The operating system's background network manager immediately sends an HTTP GET request to a dedicated vendor-neutral canary URL (e.g., Apple's http://captive.apple.com/hotspot-detect.html or Google's http://connectivitycheck.gstatic.com/generate_204) [1].
  3. DNS/HTTP Interception: The local Wireless LAN Controller (WLC) or Access Point (AP) intercepts this port 80 HTTP request. Instead of returning the expected HTTP 200 or 204 status, the gateway redirects the client's traffic to the captive portal's landing page URL via an HTTP 302 redirect [2].
  4. Webview Spawning: Detecting the redirect, the OS spawns its native Captive Network Assistant (CNA) mini-browser to display the redirected splash page, bypassing the need for the user to manually open a full browser.
  5. Authentication and State Transition: The user completes the login form, submitting credentials back to the portal server, which instructs the gateway (often via a RADIUS Access-Accept or external API call) to authorise the MAC address.
  6. CNA Exit Handshake: The CNA mini-browser performs another HTTP GET to its canary URL. If it receives the expected 200/204 response, it changes its top-right button from "Cancel" to "Done" and establishes the WiFi connection as the primary network interface.

Platform-Specific Mini-Browser Constraints

Each operating system handles this lifecycle within different webview environments, resulting in highly fragmented behaviour. The table below details these critical constraints:

Platform / Webview Display Method Persistent Cookies External Web Fonts JavaScript Execution Window Dimensions Exit Handshake Trigger
Apple iOS CNA (Websheet) Mini-Browser Popup Blocked (Destroyed on close) Blocked (Offline) Limited (No localStorage/sessionStorage) Responsive (Device-width) Full-page HTTP Redirect Only [1]
Apple macOS CNA (Captive Network Assistant) Mini-Browser Popup Blocked Blocked Limited (No alert/confirm dialogs) Fixed (900px x 572px) Full-page HTTP Redirect Only
Android (Google) (CaptivePortalLogin) Push Notification -> Chrome Custom Tab Allowed (Shared with Chrome) Allowed (If whitelisted in walled garden) Full Responsive Automatic (Captive Portal API / 204 Check) [2]
Samsung Android (Samsung Internet) Push Notification -> Mini-Browser Allowed Allowed Full Responsive Automatic
Windows 10/11 (Default Browser) Auto-Launch Default Browser Allowed (Full browser context) Allowed Full Responsive Manual / Automatic

cna_constraints_comparison.png

Coding Around the Apple CNA "Done" Button Trap

One of the most frequent failure modes in custom portal development is the "Done" Button Trap on iOS devices. When a user authenticates, the iOS Websheet webview must detect that the network is no longer captive. It does this by monitoring the success of its background canary requests.

Crucially, the iOS CNA will only trigger this check upon a full-page HTTP navigation (location redirect). If a developer builds a modern Single Page Application (SPA) that submits form data via an asynchronous AJAX call (e.g., fetch() or Axios) and updates the DOM dynamically without changing the URL, the CNA will never re-run its connectivity check. The user will be authenticated at the gateway level, but the CNA button in the top-right corner will remain as "Cancel". If the frustrated user clicks "Cancel", the iOS device will immediately disassociate from the SSID, terminating the WiFi session [1].

To prevent this, the authentication success handler must perform a full-page redirect to a physical landing page (e.g., window.location.href = '/success') or submit the login form natively via a standard HTTP POST action.

Implementation Guide

To ensure consistent rendering across all platforms, developers must transition from modern, asset-heavy web design to a highly self-contained, defensive coding style.

The Golden Rule: Design for Zero Internet Connectivity

During the captive state, the client device has no access to the wider internet. It can only resolve and access IP addresses and domains explicitly whitelisted in the wireless controller's Walled Garden (such as the IP of the captive portal server itself). Therefore, any external asset referenced in your HTML will fail to load, resulting in a broken layout.

To design defensively, implement the following Mobile-First Captive Portal Design Checklist:

mobile_first_checklist.png

1. Viewport Configuration

To prevent mobile devices from scaling down the viewport to a desktop width (typically 980px), the HTML `` must include a responsive viewport meta tag. Without this, text and input fields will appear microscopic on mobile devices:


2. Inlining CSS and Removing External Dependencies

Never link to external CSS files or CDNs (e.g., Bootstrap, Tailwind, or Google Fonts). All CSS must be embedded within a `

<div class="portal-card">
    <div class="logo-container">
        
        
            
            YOUR BRAND
        
    </div>
    
    <h1>Welcome to Guest WiFi</h1>
    <p>Please enter your details below to gain secure, high-speed internet access.</p>
    
    
    
        <div class="form-group">
            Full Name
            
        </div>
        
        <div class="form-group">
            Email Address
            
        </div>
        
        <div class="consent-group">
            
            
                I accept the <a href="#">Terms of Service</a> and consent to data processing in compliance with GDPR regulations.
            
        </div>
        
        <div id="terms_box" class="terms-scrollbox">
            <strong>WiFi Terms of Service:</strong><br />
            1. This service is provided as-is without warranties.<br />
            2. Users must not engage in illegal bandwidth-intensive activities.<br />
            3. Personal data is collected solely for authentication and marketing opt-ins in compliance with our Privacy Policy.
        </div>
        
        Connect to WiFi
    
    
    <div class="footer">
        Powered by Purple | Secure Guest WiFi
    </div>
</div>

## Troubleshooting &amp; Risk Mitigation

When deploying custom-coded HTML/CSS captive portals, IT operations teams frequently encounter several severe operational risks:

### 1. The SSL/TLS Certificate Warning Loop

Because captive portals function by intercepting traffic, they present a fundamental conflict with modern HTTPS web security. When a user attempts to visit an HTTPS site (e.g., `https://www.google.com`), and the gateway attempts to redirect that traffic to an HTTP captive portal, the browser detects a mismatch in the SSL certificate and displays a critical "Your connection is not private" security warning. 

* **Mitigation**: Never attempt to intercept HTTPS traffic directly. Rely entirely on the operating system's native CNA helper (which makes an unencrypted HTTP request to trigger the redirect). Ensure your captive portal's domain has a valid, publicly trusted SSL certificate (e.g., Let's Encrypt or DigiCert) and is served over HTTPS *only after* the initial HTTP redirect has successfully routed the user to your portal domain [2].

### 2. DNS Resolution Failures (The Walled Garden Trap)

If your custom HTML page references external resources—such as a social login OAuth endpoint (e.g., Facebook, Google) or a payment gateway—the DNS requests for these domains will fail unless they are explicitly whitelisted in the wireless controller's Walled Garden. If a domain is missing from the whitelist, the login flow will stall, presenting a blank screen.

* **Mitigation**: Maintain a strict, minimal Walled Garden list. If utilising social logins, whitelist the specific wildcard domains recommended by the identity providers (e.g., `*.google.com`, `*.gstatic.com`). 

### 3. Session Timeout and MAC Spoofing Vulnerabilities

Standard captive portals authenticate devices based on their MAC addresses. However, modern mobile operating systems (iOS 14+ and Android 10+) utilise randomised MAC addresses (private WiFi addresses) by default, rotating them periodically. This can lead to guests being repeatedly prompted to re-authenticate, destroying the user experience [1].

* **Mitigation**: Implement reasonable session timeouts (e.g., 24 hours) on the RADIUS server to prevent stale sessions, and utilise modern authentication standards like **Passpoint (Hotspot 2.0)** or **WPA3-Enterprise** for seamless, secure onboarding that bypasses MAC-based captive portals entirely.

## Purple Product Relevance: Build vs. Buy

While coding a single HTML page is straightforward, hosting, securing, and scaling a custom captive portal infrastructure presents massive technical and compliance hurdles. The table below compares the engineering and operational realities of self-hosting a custom portal versus utilising Purple's managed enterprise platform:

| Feature / Operational Requirement | Self-Hosted Custom Portal | Purple Enterprise WiFi Platform |
| :--- | :--- | :--- |
| **HTML/CSS Customisation** | Fully manual coding, uploading files to individual APs or local web servers. | **Pixel-perfect developer editor** allowing custom HTML/CSS injects, combined with a drag-and-drop visual builder.
| **RADIUS Infrastructure** | Must deploy, configure, and maintain highly available FreeRADIUS or Cloud RADIUS servers [4]. | **Built-in, globally distributed, cloud-native RADIUS** with active-active redundancy and 99.99% uptime SLAs.
| **Multi-Vendor AP Support** | Custom integration scripts required for each hardware vendor (Cisco, Aruba, Meraki, Ruckus) [5]. | **Native, out-of-the-box integration** with over 200 hardware models; unified portal deployment across mixed-hardware estates.
| **Data Privacy &amp; Compliance** | Venue assumes 100% legal liability for GDPR, CCPA, and PCI DSS compliance, including secure database encryption and data deletion workflows. | **Fully compliant by design**. Built-in consent management, automated data-subject deletion requests, and secure ISO 27001-certified hosting.
| **Analytics &amp; Marketing** | Requires building custom data ingestion pipelines and integrating third-party marketing tools. | **Enterprise-grade analytics dashboard** with real-time footfall tracking, return-rate metrics, and automated marketing campaign triggers [6].
| **Identity Provider Integrations** | Manual OAuth2 integrations with Google, Facebook, Apple, and local SMS gateways. | **One-click integrations** with major social platforms, SMS gateways, and Azure AD / Okta for corporate guests.

Purple's platform resolves the "Build vs. Buy" dilemma. It provides developers with the complete creative freedom of a custom HTML/CSS workspace while eliminating the complex, high-risk backend infrastructure engineering required to support secure RADIUS authentication at scale.

## ROI &amp; Business Impact

Investing in a professionally engineered, responsive custom captive portal delivers quantifiable returns across IT operations, marketing, and legal compliance.

### 1. Operational Cost Reduction (IT Helpdesk Tickets)

In large-scale deployments, such as a stadium or multi-site retail chain, a broken captive portal is a leading driver of IT helpdesk escalations. When guests encounter a "white screen" or a non-responsive login button, they overwhelm on-site staff or submit support tickets.

$$\text{Annual Support Savings} = (\text{Total Annual Guest Visits} \times \text{Portal Failure Rate} \times \text{Helpdesk Contact Rate}) \times \text{Cost Per Support Ticket}$$

* **Scenario**: A convention centre with 1,000,000 annual visitors. A poorly coded portal has a 5% failure rate on older iOS devices, leading to a 10% helpdesk contact rate. At an industry-standard $15 per support ticket, the operational cost is:
  $$(1,000,000 \times 0.05 \times 0.10) \times \$15 = \$75,000 \text{ annually in avoidable support overhead}$$
* **Outcome**: Transitioning to a CNA-optimised, mobile-first template reduces the portal failure rate to &lt;0.1%, virtually eliminating this operational drain.

### 2. Marketing Data Capture and Opt-in Optimisation

For retail and hospitality venues, the guest WiFi portal is the primary mechanism for capturing clean, first-party customer data. A poorly designed user interface with microscopic text or a clunky form layout causes high **bounce rates**—users abandon the login process entirely, resulting in lost marketing opportunities.

* **Case Study (Retail)**: A national retail chain implemented a mobile-first optimised captive portal utilising Purple's platform. By replacing a multi-step login form with a single-field email input (font-size: 16px) and an optimised 48px tap-target button, they saw a **42% increase in completed registrations** and a **28% increase in marketing newsletter opt-ins** within the first quarter [6].

### 3. Legal and Regulatory Risk Mitigation

Under GDPR and CCPA, non-compliant data collection carries severe financial penalties (up to 4% of global annual turnover under GDPR). Relying on pre-ticked checkboxes or failing to provide a clear, easily accessible Privacy Policy on your splash page exposes the enterprise to immense legal liability.

* **Mitigation ROI**: Implementing an explicit, un-ticked consent checkbox and hosting terms within an optimised scrollbox ensures 100% regulatory compliance, mitigating the risk of multi-million dollar regulatory fines and protecting brand reputation.

## Summary of Key Takeaways

* **The CNA Sandbox is Restrictive**: Apple's iOS Websheet and macOS CNA are highly sandboxed environments that block external assets, cookies, and web fonts. All styling and assets must be self-contained (inline CSS, Base64 images, system fonts) [1].
* **AJAX Breaks the iOS Exit Handshake**: To successfully transition the iOS device from "captive" to "connected" (changing the top-right button from "Cancel" to "Done"), you must trigger a full-page HTTP redirect. Asynchronous DOM updates will leave the device in a captive loop.
* **Mobile-First is Mandatory**: Over 90% of logins occur on mobile. Design a single-column layout (max-width: 480px), utilise touch-friendly tap targets (minimum 44px x 44px), and enforce a minimum 16px font size on all text inputs to prevent automatic iOS browser zooming.
* **Walled Gardens Control DNS**: Any external domain referenced during login (e.g., social login APIs) must be explicitly whitelisted in the wireless controller's walled garden, or the page will fail to load.
* **Purple Eliminates Backend Complexity**: Utilising Purple's portal builder gives developers complete HTML/CSS control via a custom editor, while offloading the immense security, scaling, and compliance burdens of RADIUS, multi-vendor AP integrations, and GDPR-compliant database management [3].

## References

* [1] [Wireless Broadband Alliance: Captive Network Portal Behaviour](https://captivebehavior.wballiance.com/)
* [2] [Android Open Source Project: Captive Portal Login Webview Integration](https://source.android.com/docs/core/connect/android-custom-tabs-captive-portal)
* [3] [European Data Protection Board: Guidelines on Consent under Regulation 2016/679](https://edpb.europa.eu/our-work-tools/our-documents/guidelines/guidelines-052020-consent-under-regulation-2016679_en)
* [4] [How to Implement 802.1X Authentication with Cloud RADIUS](/guides/implementing-8021x-with-cloud-radius)
* [5] [Cisco Wireless APs: 2026 Guide to Products &amp; Deployment](/blog/cisco-wireless-ap)
* [6] [Purple WiFi Marketing &amp; Analytics Platform](/guest-wifi-marketing-analytics-platform)

---

## Listen to the Technical Briefing

Listen to a senior solutions architect discuss the technical constraints and implementation strategies for custom captive portals:

Definiciones clave

Captive Portal

Una página web que se muestra a los usuarios recién conectados a una red Wi-Fi antes de que se les conceda un acceso más amplio a los recursos de la red, utilizada normalmente para la autenticación, el pago o la visualización de las condiciones del servicio.

Los equipos de TI implementan Captive Portals a nivel de puerta de enlace para controlar el acceso de los invitados, capturar datos de los usuarios y garantizar el cumplimiento legal.

Captive Network Assistant (CNA)

Un mini-navegador en sandbox altamente restringido que los sistemas operativos (como Apple iOS y macOS) inician automáticamente al detectar una redirección de red cautiva, diseñado únicamente para facilitar la autenticación en el portal.

Las vistas web de CNA imponen limitaciones estrictas, como el bloqueo de CDN externas, cookies persistentes y almacenamiento local, lo que con frecuencia rompe los diseños web estándar.

Walled Garden

Una lista restringida de direcciones IP, subredes o nombres de dominio a los que un usuario invitado no autenticado tiene permiso para acceder a través de la puerta de enlace antes de completar el proceso de inicio de sesión del Captive Portal.

Los desarrolladores deben asegurarse de que cualquier recurso externo (como las API de inicio de sesión social o las pasarelas de pago) esté en la lista de permitidos del walled garden para evitar que el flujo de inicio de sesión se detenga.

Base64 Encoding

Un esquema de codificación de binario a texto que representa datos binarios (como imágenes) como una cadena ASCII, lo que permite incrustar recursos directamente dentro de documentos HTML o CSS.

El uso de la codificación Base64 para logotipos e iconos elimina las solicitudes HTTP externas, lo que garantiza que los recursos se rendericen perfectamente en entornos CNA sin conexión.

RADIUS (Remote Authentication Dial-In User Service)

Un protocolo de red que proporciona una gestión centralizada de autenticación, autorización y contabilidad (AAA) para los usuarios que se conectan y utilizan un servicio de red.

El servidor del Captive Portal se comunica con un servidor RADIUS para autorizar la dirección MAC del invitado en la puerta de enlace de red una vez que se cumplen los criterios de autenticación.

System Font Stack

Una declaración font-family de CSS que prioriza las fuentes del sistema operativo preinstaladas (como San Francisco en iOS, Segoe UI en Windows y Roboto en Android) sobre las fuentes web externas.

La implementación de una pila de fuentes del sistema garantiza el renderizado inmediato de la tipografía sin activar solicitudes HTTP externas bloqueadas a servicios como Google Fonts.

Canary URL

Una URL HTTP dedicada y no cifrada mantenida por los proveedores de sistemas operativos (por ejemplo, captive.apple.com) para comprobar si un dispositivo tiene conectividad a Internet sin restricciones.

El administrador de red en segundo plano del sistema operativo comprueba esta URL para detectar la presencia de un Captive Portal y activar la ventana emergente de la vista web de CNA.

Passpoint (Hotspot 2.0)

Un estándar del sector desarrollado por la Wi-Fi Alliance que permite a los dispositivos móviles descubrir y autenticarse automáticamente de forma segura con puntos de acceso Wi-Fi, evitando los inicios de sesión manuales en Captive Portals.

Las empresas utilizan Passpoint junto con plataformas como Purple para que los invitados pasen de páginas de bienvenida con mucha fricción a experiencias de itinerancia seguras y fluidas similares a las de la telefonía móvil.

Ejemplos prácticos

Una cadena de hoteles de lujo de 250 habitaciones [Hospitality](/industries/hospitality) desea implementar una página de inicio de sesión de WiFi para invitados personalizada que se adapte perfectamente a las directrices de su marca premium. Su agencia creativa diseñó una página de bienvenida que utiliza tipografía de marca personalizada (alojada en Adobe Fonts), múltiples imágenes de fondo de alta resolución (alojadas en un bucket público de AWS S3) y un asistente de JavaScript animado de varios pasos. Al implementarlo, los invitados con iOS se conectan al SSID, pero el portal aparece como una pantalla blanca en blanco y los usuarios no pueden autenticarse.

Para resolver la pantalla en blanco y el diseño de marca roto, debemos reestructurar la arquitectura frontend del portal para cumplir con las restricciones del sandbox de Apple CNA:

  1. Corrección de la tipografía: Dado que Adobe Fonts requiere una solicitud HTTP externa que está bloqueada por el CNA, reemplazamos la llamada a la fuente personalizada con una pila de fuentes del sistema nativa y premium (font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;). Esto garantiza un renderizado instantáneo sin llamadas de red externas.
  2. Optimización de recursos: Las imágenes de fondo en AWS S3 están bloqueadas porque S3 no está en el walled garden de la puerta de enlace. Comprimimos el logotipo principal de la marca, lo convertimos a un SVG ligero y lo codificamos directamente en el HTML como un URI de datos Base64. Para el fondo, reemplazamos las imágenes pesadas con un degradado CSS limpio y adaptable que utiliza los colores de la marca del hotel, reduciendo significativamente el peso de la página.
  3. Simplificación de JavaScript: El asistente animado de varios pasos depende de bibliotecas externas de jQuery y GSAP. Eliminamos estas dependencias externas y refactorizamos el formulario en una estructura HTML de una sola columna y una sola página. La validación del formulario se reescribe en JavaScript nativo y ligero.
  4. Protocolo de autenticación: El envío del formulario se modifica de un envío basado en AJAX a un <form action="/submit" method="POST"> HTML nativo para activar una redirección de página completa, lo que permite que el Websheet de iOS ejecute su comprobación canary y muestre el botón 'Done'.
Comentario del examinador: Este escenario representa el conflicto clásico entre el diseño creativo de alta gama y las estrictas restricciones de seguridad de las vistas web cautivas. Las agencias creativas suelen tratar el Captive Portal como un sitio web de escritorio estándar. Sin embargo, debido a que el dispositivo se encuentra en un estado previo a la autenticación, la red bloquea todo el tráfico externo. Al integrar CSS en línea, usar fuentes del sistema, codificar recursos en Base64 y utilizar envíos de formularios nativos, preservamos la estética de la marca premium al tiempo que logramos una confiabilidad operativa del 100% en dispositivos iOS y Android.

Una cadena minorista nacional [Retail](/industries/retail) con 450 tiendas desea capturar los correos electrónicos de los invitados a través de páginas de bienvenida de WiFi para alimentar su CRM. Requieren que los invitados acepten recibir boletines de marketing. El diseño inicial tiene una casilla de verificación premarcada que dice 'Acepto recibir correos electrónicos de marketing'. Además, el portal está alojado en un único servidor local en su sede central. Durante las horas pico (sábado por la tarde), los invitados de todo el país experimentan retrasos graves y muchos no pueden cargar la página de inicio de sesión, lo que provoca una caída masiva en las tasas de captura de datos.

Debemos abordar tanto la infracción de cumplimiento como el cuello de botella de la infraestructura:

  1. Corrección de cumplimiento: Según el GDPR y la CCPA, las casillas de consentimiento premarcadas son ilegales. Modificamos el HTML para que la casilla de consentimiento de marketing esté desmarcada por defecto (<input type="checkbox" id="marketing_consent">). También agregamos una casilla de verificación obligatoria y separada para las Condiciones del servicio para desvincular el acuerdo legal del consentimiento de marketing.
  2. Escalado de infraestructura: Alojar un Captive Portal nacional en un único servidor centralizado crea un punto único de fallo y un cuello de botella de latencia masivo. Migramos el frontend del portal a una red de entrega de contenido (CDN) altamente disponible y distribuida globalmente con almacenamiento en caché en el borde.
  3. Integración de RADIUS: Configuramos los puntos de acceso de las tiendas locales para que apunten a un clúster RADIUS nativo de la nube con redundancia activo-activo, lo que garantiza que las solicitudes de autenticación se procesen localmente en el borde con una latencia inferior a 50 ms, incluso durante el tráfico pico de los sábados.
  4. Migración a Purple: Para eliminar toda esta sobrecarga de ingeniería, el minorista migra a Purple. Las herramientas de consentimiento de GDPR integradas de Purple gestionan automáticamente las suscripciones conformes, y su infraestructura en la nube distribuida globalmente gestiona millones de autenticaciones diarias con un tiempo de actividad del 99,99%, resolviendo por completo el cuello de botella de escalado.
Comentario del examinador: Las casillas de consentimiento premarcadas representan un riesgo grave de cumplimiento que puede dar lugar a multas regulatorias masivas. Desvincular el consentimiento de marketing de las Condiciones del servicio es una práctica recomendada tanto técnica como legal. En el lado de la infraestructura, el alojamiento centralizado de Captive Portals es un antipatrón. Una presencia minorista a nivel nacional requiere un frontend descentralizado con almacenamiento en caché en el borde combinado con un backend RADIUS nativo de la nube. Migrar a una plataforma gestionada como Purple elimina esta complejidad arquitectónica, lo que permite al minorista centrarse en las campañas de marketing en lugar de en el escalado de bases de datos.

Preguntas de práctica

Q1. Un equipo de TI de un importante aeropuerto internacional [Transport](/industries/transport) implementa un Captive Portal codificado a medida. Observan que, mientras que los usuarios de Android se conectan sin problemas, una parte significativa de los usuarios de iOS experimenta un problema por el cual se autentican correctamente pero no pueden navegar por la web. Al examinarlo más de cerca, los dispositivos iOS muestran que están conectados al SSID, pero el botón superior derecho de la ventana emergente cautiva sigue diciendo 'Cancel' en lugar de 'Done'. ¿Cuál es la causa raíz de este problema y cómo debería solucionarlo el desarrollador?

Sugerencia: Analice cómo el asistente de Apple CNA detecta que una red ha pasado de cautiva a autenticada, y qué acción del navegador se requiere para activar esta comprobación.

Ver respuesta modelo

La causa raíz es que la página de éxito del portal actualiza la interfaz de usuario de forma dinámica a través de JavaScript (enrutamiento AJAX/SPA) en lugar de realizar una navegación HTTP de página completa. El mini-navegador Captive Network Assistant (CNA) de Apple iOS solo vuelve a ejecutar su comprobación de conectividad en segundo plano (la solicitud canary a captive.apple.com) cuando se produce una redirección o navegación de URL de página completa. Si el desarrollador envía el formulario de inicio de sesión a través de AJAX y simplemente muestra un mensaje de 'Éxito' en el DOM, el CNA no se enterará de que la red se ha desbloqueado. En consecuencia, el botón superior derecho sigue siendo 'Cancel'. Si el usuario hace clic en 'Cancel' para salir, el sistema operativo asume que el inicio de sesión falló y se desconecta de la red WiFi.

Solución: El desarrollador debe modificar el controlador de éxito de autenticación para forzar una redirección de página completa. Esto se puede lograr enviando el formulario de inicio de sesión de forma nativa a través de un <form action="/submit" method="POST"> HTML estándar o ejecutando window.location.href = '/success_landing_page' en JavaScript una vez que la API devuelva una respuesta de autenticación correcta. Esto activa la carga de página completa requerida, lo que obliga al asistente de CNA a volver a evaluar el estado de la red, verificar que la URL canary ahora es accesible y cambiar el botón superior derecho a 'Done'.

Q2. Un equipo de operaciones de un estadio [Events] desea lanzar una red WiFi para invitados que capture suscripciones de marketing. El responsable de cumplimiento insiste en que el portal debe cumplir al 100% con el GDPR. El equipo de desarrollo presenta una maqueta en la que el formulario de inicio de sesión tiene una casilla premarcada que dice 'Acepto las Condiciones del servicio y doy mi consentimiento para recibir boletines de marketing'. ¿Por qué este diseño no cumple con la normativa y cómo se debería refactorizar el HTML/CSS y la estructura del formulario para cumplir con el GDPR manteniendo una alta tasa de conversión?

Sugerencia: Tenga en cuenta los estrictos requisitos del GDPR en relación con el consentimiento explícito, la desvinculación de las suscripciones de marketing de las condiciones del servicio y la visibilidad física del texto legal en las pantallas de los móviles.

Ver respuesta modelo

El diseño propuesto infringe el GDPR en dos aspectos principales: en primer lugar, las casillas de verificación premarcadas no constituyen un consentimiento válido, que debe ser libre, específico, informado e inequívoco. En segundo lugar, agrupar el consentimiento de marketing con la aceptación de las Condiciones del servicio no cumple con la normativa; no se puede obligar a un usuario a aceptar correos electrónicos de marketing como condición para utilizar el servicio WiFi.

Estrategia de refactorización:

  1. Desvincular el consentimiento: Divida la casilla de verificación en dos casillas independientes. La casilla A es obligatoria y cubre las Condiciones del servicio y la Política de privacidad. La casilla B es opcional y cubre la suscripción al boletín de marketing.
  2. Establecer como desmarcada: Asegúrese de que ambas casillas estén desmarcadas por defecto en el HTML (omitiendo el atributo checked).
  3. Visibilidad de CSS: Dado que más del 90% de los usuarios utilizan dispositivos móviles, coloque las casillas de verificación directamente encima del botón 'Connect' para que sean visibles en la parte superior de la página sin necesidad de desplazarse. Utilice una pila de fuentes del sistema y establezca el tamaño de fuente de la etiqueta en 14px con una altura de línea de 1.4 para facilitar la lectura.
  4. Cuadro de desplazamiento de condiciones: Para evitar que el texto legal desplace los elementos del formulario fuera de la pantalla, coloque las Condiciones del servicio detalladas en un contenedor desplazable con una altura fija (max-height: 100px; overflow-y: auto; background-color: #F5F1ED; border: 1px solid #D1D5DB; border-radius: 6px;) que se pueda abrir o cerrar mediante un enlace de texto. Esto mantiene un diseño limpio y de alta conversión, al tiempo que garantiza el cumplimiento legal absoluto.

Q3. Una cadena minorista [Retail](/industries/retail) está implementando una página de bienvenida codificada a medida en 100 tiendas. El diseñador utilizó Google Fonts (Montserrat) y enlazó a una hoja de estilo Bootstrap alojada en CDN en la cabecera HTML. Durante las pruebas en una red corporativa, la página se renderiza perfectamente. Sin embargo, cuando se implementa en un AP de tienda de prueba con una configuración de red cautiva, la página se renderiza con texto Times New Roman sin estilo, alineación rota e iconos faltantes. ¿Por qué ocurre esto y cómo se deben refactorizar los recursos?

Sugerencia: Analice el estado de la conexión de red antes de que se autentique un usuario y determine cómo gestiona el navegador las solicitudes HTTP externas a dominios fuera del walled garden.

Ver respuesta modelo

Este fallo se produce porque el dispositivo se encuentra en un estado cautivo y no autenticado cuando se carga la página de bienvenida. En este estado, la puerta de enlace inalámbrica bloquea todo el tráfico de Internet saliente, permitiendo solicitudes únicamente a los dominios incluidos explícitamente en la lista de permitidos del Walled Garden de la puerta de enlace. Dado que los dominios de CDN para Bootstrap (cdn.jsdelivr.net) y Google Fonts (fonts.googleapis.com) no están en la lista de permitidos, las solicitudes del navegador para obtener la hoja de estilo y los archivos de fuentes fallan silenciosamente. En consecuencia, el navegador recurre a su motor de renderizado predeterminado, lo que da como resultado un HTML sin estilo (texto en Times New Roman) y diseños rotos.

Estrategia de refactorización:

  1. CSS en línea: Elimine el enlace externo a la hoja de estilo de Bootstrap. Copie las reglas de CSS grid/flexbox necesarias directamente en un bloque <style> en el <head> del HTML. Esto garantiza que todas las instrucciones de diseño se entreguen en la carga útil inicial de una sola página.
  2. Implementar una pila de fuentes del sistema: Elimine la llamada @import o <link> de Google Fonts. Reemplácela con una pila de fuentes del sistema nativa en el CSS (font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;). Esto obliga al dispositivo a utilizar fuentes de alta calidad ya preinstaladas en el sistema operativo, eliminando por completo la dependencia de la red externa.
  3. Codificar iconos/logotipos en Base64: Si el diseño depende de imágenes externas o bibliotecas de iconos (como FontAwesome), convierta estos iconos al formato SVG e incrústelos en línea dentro del HTML o como URI de datos Base64 en el CSS. Esto garantiza que la página sea 100% autónoma y se renderice perfectamente incluso con cero conectividad a Internet.

Continúe leyendo esta serie

Diseño de Captive Portals B2B: Captura de nombres registrados y datos de la empresa

Esta guía proporciona a los directores de TI y operadores de recintos un marco técnico independiente del proveedor para diseñar Captive Portals B2B. Detalla cómo estructurar los campos de registro para capturar el nombre registrado y los datos de la empresa, garantizando altas tasas de finalización a la vez que se mantiene el cumplimiento del GDPR y se genera inteligencia a nivel de cuenta.

Leer la guía →

Arquitectura de Captive Portal: seguridad, redirección y mejores prácticas

Una referencia técnica definitiva sobre la arquitectura de Captive Portal empresarial. Esta guía analiza el aislamiento de red, la redirección de DNS, la autenticación RADIUS y el cumplimiento de seguridad para líderes de TI que implementan redes WiFi de invitados seguras y ricas en datos.

Leer la guía →

Optimización de Captive Portals B2B: Captura de Nombres de Empresa y Datos Profesionales

Esta guía explica cómo los responsables de TI, arquitectos de red y directores de operaciones de instalaciones pueden configurar Captive Portals B2B para capturar datos profesionales —nombres de empresas, cargos y direcciones de correo electrónico corporativas— en el momento de iniciar sesión en el WiFi. Cubre toda la arquitectura técnica, desde el aislamiento de VLAN y la autenticación RADIUS hasta la integración de CRM con Salesforce y HubSpot, con cumplimiento integrado de GDPR y CCPA. Las instalaciones que implementan esto correctamente convierten su red WiFi de invitados en un motor de datos de origen y en un sistema automatizado de generación de leads.

Leer la guía →