Personalizando aplicaciones web en tiempo real

Los invisibles de la CDN

Siempre es un reto, tanto a nivel diseño como de desarrollo, personalizar o themificar aplicaciones web, especialmente cuando hay una diversidad de identidades de marca y resellers de servicio involucrados.

Como arquitecto de soluciones front-end, mi trabajo es planificar, ejecutar y aportar soluciones que sean simples y no añadan complejidad innecesaria a nivel técnico. Busco, en la medida de lo posible, facilitar el uso tanto para el usuario como para el cliente. 

Para ello siempre aplicamos nuestra metodología KISS (Keep It Simple Stupid), buscando que dichas soluciones, llenen el vacío que pretenden solventar y/o mejoren el rendimiento si reemplazan una funcionalidad o arquitectura existente y que sobre todo, sean usables.

En busca de soluciones óptimas

La necesidad de que cada empresa o reseller de nuestro servicio pueda identificar el producto con su marca, planteó un desafío para nuestro equipo: encontrar la manera más eficiente de ofrecer una personalización en tiempo real. 

A primera vista para cubrir este requerimiento se debían duplicar entornos, establecer estilos, assets y código dependiente de la propia imagen de marca, para que cuando se lleve a cabo la compilación de estáticos, cada reseller pueda obtener su espacio personalizado.

Exploramos varias ideas para abordar este caso de uso, pero cada solución propuesta parecía difícil de mantener a largo plazo y generaba más necesidades y tareas de las que buscábamos. Por lo tanto, las descartamos y continuamos buscando una solución óptima.

Do something today that your future self will thank you for

Cuando llega la inspiración

Entonces nos sumergimos en la documentación, realizamos pruebas de concepto y nos permitimos momentos de reflexión para despejar nuestras mentes en forma de paseitos que es sabido que ayudan a pensar con mejor claridad. Y, efectivamente, parece que funcionan; los resultados hablan por sí mismos. 

La idea surgió en forma de pregunta, ¿por qué no crear una imagen de marca simplemente segmentando por URL en tiempo real en base a un fichero de configuración? El resultado fue la creación de un pequeño ecosistema de herramientas, que bien comunicadas y organizadas, nos permiten hacer precisamente eso.

El ecosistema de herramientas

  • Control el acceso vía URL

Inicialmente controlábamos que cada visita a una URL de la web app correspondiera a un dominio/subdominio específico. Más adelante implementando una serie de middlewares de ruta en nuestro router (vue-router) vimos que era algo común.  Por lo tanto, trasladamos esta funcionalidad desde nuestro punto de entrada de vue (APP, main, etc) a un middleware de control de tema y personalización que integramos en nuestro pipeline de middlewares para el control de acceso de rutas.

  • Carga dinámica de variables de estilo

Para la carga dinámica debíamos resolver el problema de que Stylus (podríamos haber usado scss o sass también) y CSS no permiten el cambio de color en tiempo de ejecución cuando se cargan vía fichero.  En otras palabras, no podemos escribir las variables de manera dinámica. Por ejemplo, si tenemos variables de color del estilo $primary, $secondary, etc… (solo por mencionar algunas y hay más, ya que es posible setear espaciados, sombreados, fuentes y mil otras cosas), esto hará que durante la ejecución de nuestro build con webpack (o el empaquetador que usemos), los estilos se generan basados en estas variables solo la primera vez, sin la capacidad de que cambien en tiempo real.

La solución que encontramos es setear dichas variables en nuestro CSS con un default y luego, gracias a nuestra biblioteca de utilidades, podemos almacenar y sobrescribir estas variables en la etiqueta :root de nuestro tag <html>.

Un ejemplo de defaults y cómo se podrían usar para permitir la carga y cambio dinámico de estilos pre-definidos en nuestro elemento root:

Puedes leer más sobre CSS custom properties en https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties

  • Control de imagen de marca

Una vez que hemos identificado desde qué dominio o URL nos están visitando y tenemos las variables en nuestro CSS, el siguiente paso es cargar las distintas variables de estilo desde un archivo de configuración. Para ello, hemos creado un archivo JSON que contiene la URL y todas las opciones de personalización disponibles. De esta manera, solo necesitamos consultar este archivo para obtener las variables y cargarlas en nuestro HTML.

Control de imagen de marca
  • Persistencia

Llegados a este punto es crucial agregar una capa de rendimiento, por lo que tenemos que persistir datos. Para lograr esto, podemos utilizar herramientas como Vuex, Pinia, o incluso el objeto LocalStorage del navegador. Esta persistencia nos permite almacenar los datos del theme si aún no los tenemos, para la próxima vez validar la ausencia de cambios en el tema o en el dominio durante la carga de la URL visitada. Gracias a esto, cambiar colores, imágenes u otros elementos resulta extremadamente sencillo.

Pros vs contras

Pros:

  • Agilidad, sencillez y rapidez
  • Dar de alta un reseller solo supone modificar un JSON y apuntar un dominio/subdominio
  • Agregar assets al proyecto no implica subirlos al repo del proyecto ya que tenemos un gestor de estáticos enlazado desde el frontal
  • No hay peticiones extra para obtener la configuración
  • Es muy cómodo de mantener
  • Inmediatez y rendimiento en la carga de imagen de marca
  • En nuestro caso, la mayor parte de variables son usables en cualquier componente, por lo que un sitio único donde mantener todas las variables (:root) hace que esté todo centralizado a la hora de hacer estos cambios

Contras:

  • Principalmente que meter en :root todas las variables hace que el código pierda modularidad (en este caso particular, hemos preferido mantenibilidad sobre modularidad), ya que nos podríamos beneficiar definiendo local-scopes y usando fallbacks por clase para acotar el uso de las variables

Puedes ver cómo gestionar de forma modular tus variables aquí: https://css-tricks.com/breaking-css-custom-properties-out-of-root-might-be-a-good-idea

Resultados personalizados en tiempo real

En nuestra app y durante el build de la misma establecemos valores predeterminados para las variables de estilo. Minificando y haciendo compresión y/o hashing de ficheros, el frontal del cliente/reseller va a disponer de esos valores por defecto y de las variables que luego, codificadas de manera adecuada, permiten realizar modificaciones según los criterios que establezcamos.  

En nuestro caso, estos criterios se basan en la URL o dominio/subdominio, pero podrían ser también un selector en la interfaz con comunicación y persistencia a través de una API REST, por ejemplo.  

Así nos aseguramos que durante la ejecución de la aplicación, cada usuario pueda disfrutar de una personalización adaptada a sus necesidades individuales.

Autor: Antonio Gregorio Bacete Ramírez

Antonio Bacete Ramírez es Frontend Solutions Architect en Transparent Edge. Se interesa especialmente en la innovación y la usabilidad front aplicada en cada proyecto que desarrolla. Tiene conocimiento avanzado en otros lenguajes y frameworks y es uno de los grandes referentes del equipo tech.