El Infierno de los WebView en Flutter

Video thumbnail

Quiero compartir una reflexión, un poco más personal, sobre mi trabajo y lo que considero la pesadilla de los WebViews en Flutter, al igual que te explicaba la pesadilla de integrar una pasarela de pago como PayPal en Flutter.

Algo que parece tan sencillo, o al menos yo lo percibo desde ese enfoque (sin haber creado un navegador, por supuesto), es la capacidad de interpretar HTML. Todos comenzamos nuestro camino en el desarrollo de software, o al menos la mayoría, creando un "Hola Mundo" con HTML. A partir de ahí, avanzamos a JavaScript, CSS, y luego a lenguajes de programación más robustos (PHP, Python, Node). Por esta razón, mi visión es que la capa de HTML, CSS y JavaScript siempre debería ser sencilla de manejar.

Cuando intentamos utilizar este contenido en aplicaciones móviles —como es el caso de Desarrollo Libre, una aplicación que desarrollé en Flutter y sigo mejorando—, su núcleo es precisamente HTML, porque la fuente es una página web. Obviamente, quiero aprovechar ese contenido para que los usuarios puedan verlo fácilmente.

Todos empezamos programando con HTML. No es un lenguaje “de verdad”, pero oye, te pone a construir cosas rápido. Por eso, cuando quise usar HTML dentro de mi app en Flutter, pensé que iba a ser igual de fácil.

De hecho, en mi app de DesarrolloLibre el núcleo es HTML, y la lógica es simple:
si ya tengo mi contenido HTML, ¿por qué no usarlo también dentro de la app Flutter?

Bueno… sí, suena lógico, pero no funciona así.

El Problema de la Renderización Multiplataforma

El detalle es que la implementación es extraña y desigual. Fíjate que aquí, en Mac (donde estoy trabajando ahora), siempre encuentro estructuras raras, como puedes ver.

Mientras que en Windows, Android, e incluso iOS (aunque aún no he lanzado la aplicación), el contenido HTML se ve renderizado de forma aceptable (salvando el tema de los estilos CSS, que es otro asunto), en Mac tengo problemas de estructura. Voy a una página que estoy trabajando para que veas el resultado: aquí se ve decente, con su CSS, y estoy colocando directamente el HTML.

❓ ¿Por qué Google y Flutter No Crean una API Nativa?

El verdadero horror es que trabajar con el Webview es una pesadilla, y no entiendo por qué la gente de Google o de Flutter no implementa un Webview que sea bueno y que forme parte de la API estándar.

No creo que sea una operación tan complicada. Ya existe un Webview nativo en Android y creo que también en iOS. Por lo tanto, no sé por qué no emplean o crean una API interna que consuma ese Webview nativo de cada uno de los sistemas operativos. En Windows y macOS aún no he desarrollado aplicaciones nativas, sino que uso Flutter, pero estoy seguro de que debe existir una solución. Esto es lo que me parece sumamente extraño.

La realidad: cada plataforma hace lo que quiere

En Android me aparecía con estilos.
En Windows se veía más o menos.
En macOS… bueno, ahí directamente parecía otra página.

Y eso que era el mismo HTML.

Ahí fue cuando entendí que Flutter no tiene un WebView estándar y que cada plugin hace lo que puede con su plataforma.

La Búsqueda Infinita de Paquetes (pub)

Como puedes suponer, para implementar esta funcionalidad, usamos una extensión o un paquete de .pub. Esto es un poco como usar Flask, donde instalas la base y luego empiezas a instalar paquetes y plugins para nutrir el proyecto.

Sí, instalamos el paquete, pero el resultado es bastante horrible. Estoy volviéndome loco buscando un Webview funcional para Mac, y realmente se me ha hecho muy complicado encontrarlo.

Muchos Paquetes de Webview para Flutter

He encontrado varios Webviews disponibles en la web. En una página que encontré recientemente, donde estoy investigando, tenemos varios:

https://fluttergems.dev/webview/

Pero fíjate lo extraño del asunto o lo que me parece extraño este es para Android e iOS estos los utilice en el proyecto de DesarrolloLibre:

  webview_flutter: 4.7.0
  webview_windows:
  desktop_webview_window:
  # webview_all:

Otros me dieron errores y otros, otros dicen que funciona para Mac y no han sido probados; lo que quiero notar aquí es que tenemos muchísimos y varios no funcionan como se espera.

Cómico porque hay uno que dice que está abierto para todas las plataformas pero no lo ha testeado en MacOS

Otros los probe y dieron error al ejecutar la app o instalarlos.

Pero a lo que me refiero un poco es eso que se hace un poco pesadilla en ese sentido porque no hay uno como que estandarizado

webview_flutter: oficial, pero lejos de ser perfecto

El plugin oficial funciona, sí… pero:

  • No está 100% a nivel de Android/iOS.
  • Para macOS y Windows es otra historia.
  • Y para HTML como string, olvídalo si quieres consistencia.

En mi caso terminé activando JavaScript, controlando el WebView con un WebViewController y aún así había funciones que no iban igual entre plataformas.

Plugins alternativos: webview_windows, desktop_webview_window y compañía

Aquí fue cuando entré al mundo oscuro de los plugins:

webview_flutter: 4.7.0
webview_windows:
desktop_webview_window:
# webview_all:

Algunos:

  • se instalaban pero daban error al ejecutar,
  • otros decían “funciona en macOS” pero no lo habían probado,
  • otros directamente no renderizaban HTML embebido.

Uno incluso decía soportar todas las plataformas, pero tenía la etiqueta “not tested”. Literalmente.

El caos del soporte multiplataforma (y los que dicen “macOS supported” sin probarlo)

Cuando un plugin pone “macOS support” pero luego aclara “no testing”, lo que realmente significa es:

“Aquí nadie probó nada. Suerte si funciona.”

Y sí, lo comprobé por las malas.

Contenido HTML Variable y el Desafío del WebView

Otro problema que encuentro con los WebViews es la dificultad para manejar el contenido HTML variable. A menudo, tengo código HTML que quiero inyectar, y muchos plugins simplemente no lo muestran, no lo manejan bien, o el resultado es confuso.

La mayoría de los WebViews se enfocan en renderizar contenido a partir de una URL completa, lo cual es muy diferente a renderizar un fragmento de código HTML puro y simple. Desde una aplicación web nativa (donde todo es HTML), esta tarea es trivial. Sin embargo, en un entorno como Flutter, donde dependemos de tantos plugins y formas de interpretar el contenido HTML, se convierte en una verdadera pesadilla.

Usar un WebView Consistente en Todas las Plataformas: Una Tarea Imposible

Con todo lo expresado, se entiende por qué titulé mi publicación de esta manera: Algo tan sencillo como la necesidad de emplear contenido HTML en una app de Flutter, ya sea suministrando una URL o un código HTML directo, se vuelve una tarea extremadamente compleja en diversos sistemas operativos.

Los plugins actuales:

  • No funcionan en todas las plataformas (o presentan bugs en algunas específicas).
  • Solo aceptan una URL y fallan con contenido HTML directo.
  • Incluyen advertencias en su documentación, como "está en beta" o "no ha sido testeado" (No Testing), a pesar de que la plataforma se enumera como disponible.

Diferencias de renderizado entre Android, Windows y macOS

En macOS en particular, el HTML parecía otra página.
En Windows sí funcionaba, pero a veces ignoraba el CSS.
En Android… bueno, ahí por lo menos pude avanzar.

Plugins que fallan al instalar o ejecutar

Me pasó varias veces: instalas, corres… error desde el arranque.
O advertencias tipo “este paquete está en beta”.
O directamente nada funciona.

El vacío absoluto de documentación oficial

No hay guía oficial para:

  • HTML embebido
  • CSS interno
  • compatibilidad Windows/macOS
  • performance
  • WebViews multipantalla

Literalmente te toca adivinar.

La Falta de Documentación y Coherencia

Si un paquete dice estar disponible para macOS, pero luego indica "No Testing" justo al lado, ¿qué debemos entender? Yo interpreto que el paquete nunca ha sido probado en Mac, y si los propios desarrolladores no lo han probado, no entiendo cómo lo colocan como opción. Aparte de esta incoherencia, la documentación oficial para la mayoría de estos pubs es, básicamente, nula.

Cómo elegí un WebView “suficientemente funcional” para cada plataforma

Android: relativamente estable

El oficial funciona. JavaScript funciona. HTML string… depende, pero viable.

iOS: permisos y previsualizaciones

Hay que activar la vista embebida en Info.plist, si no ni arranca.

Windows: opciones limitadas

Aquí plugins como webview_windows ayudan, pero no esperes milagros.

macOS: la plataforma donde casi nada funciona como debería

Aquí puedo decir que los plugins que “funcionaban” tenían siempre un asterisco:

  • no soporta string HTML
  • no ejecuta scripts
  • falla al abrir CSS
  • o simplemente no renderiza

Mi solución final: código multiplataforma con condicionales

Después de muchas pruebas, esto es lo que terminé haciendo:

if (Platform.isAndroid) {
 // un plugin
}
else if (Platform.isWindows) {
 // otro plugin
}
else if (Platform.isMacOS) {
 // solución alternativa
}

Conclusión: Un Desarrollo Artesanal y Personalizado

Quería compartir mi perspectiva con todo esto para que tú mismo saques tus propias conclusiones al planificar tu desarrollo.

En el proyecto Desarrollo Libre, necesito emplear HTML tanto a nivel de enlace como de código HTML inyectable. Al final, para lograr simplemente renderizar un contenido HTML de forma fiable, tuve que recurrir a un desarrollo extenso y personalizado, creando métodos propios con múltiples condicionales que devuelven el resultado en función de la plataforma empleada y el WebView que se soporta en ese entorno específico.

if(Platform.isAndroid){
}

Mi recomendación general:

  • Android/iOS → webview_flutter (con trabajo extra).
  • Windows → webview_windows.
  • macOS → solo usar WebView si es indispensable; si no, buscar alternativas.
  • HTML como string → probar antes de comprometerte con un plugin.
  • Widgets complejos como TradingView → funcionan solo en ciertas plataformas.

Si esperas que “cargar HTML en Flutter” sea tan fácil como suena…
Prepárate: es posible, pero vas a escribir código condicional como si vivieras en 2010.

❓ Preguntas frecuentes

  • ¿Cómo cargar HTML como string en Flutter?
    • Con loadHtmlString (cuando el plugin lo soporta). No todos lo hacen.
  • ¿Qué plugin usar para Windows o macOS?
    • Windows: webview_windows.
      macOS: muy pocos funcionan bien. Hay que probar caso por caso.
  • ¿Cómo hacer que WebView soporte JavaScript?
    • Con: javascriptMode: JavascriptMode.unrestricted

Aunque, en este articulo te indico una solución mejor, convertir el Texto HTML a widgets.

Acepto recibir anuncios de interes sobre este Blog.

Hablaré de los problemas que he tenido al intentar mostrar contenido HTML mediante una URL o un código en distintas platagormas en Flutter.

| 👤 Andrés Cruz

🇺🇸 In english