¿Qué es la famosa «arquitectura de islas» en desarrollo web?

El creador de Preact, Jason Miller, escribió en 2020 este artículo donde explicaba el concepto de la «Arquitectura de Islas» que introdujo por primera vez Katie Sylor-Miller (@ksylor), arquitecta frontend de Etsy.

Ha sido relativamente difícil de implementar hasta que ha llegado Astro, un framework que precisamente está pensado para construir páginas con arquitectura de islas.

La idea es pensar en una página web generada en el servidor, enviada hacia el navegador, y que contenga todo el contenido estático, pero con pequeños elementos repartidos que por la razón que sea, necesitan ser dinámicos. Estos componentes son las llamadas «islas».

Es decir, en lugar de tener una web donde todo a la vez sea dinámico, sobrecargado de scripts y que nuestra aplicación tenga un control total sobre el renderizado de la página, con las «islas interactivas» se consigue aislar ese comportamiento y «hidratar» componentes de forma independiente y cuando sea necesario.

image 1
Esquema de componentes sin y con hidratación

Las partes de una web que son puramente estáticas y no tienen interacción (como por ejemplo, el contenido de un artículo) se dice que «no tienen hidratación», y por lo tanto, no son más que porciones de HTML puro y estático. En cambio, las regiones de dicha página que necesiten interactividad, la aplicación se encarga de «hidratarlos», como por ejemplo un widget con botones de compartir en redes sociales.

Ya no priorizamos el rendimiento y la optimización

El problema que tenemos hoy en día es que muchas páginas están tan cargadas de recursos y sobre todo JavaScript, que son mucho más lentas de lo que pensamos incluso quienes desarrollamos. Nos parece normal que una página tarde 5 segundos en cargar y no somos conscientes de toda la basura que le enviamos al navegador para que procese antes de mostrar contenido o que la web sea interactiva.

A veces, generamos decenas de ficheros y pequeñas librerías JavaScript que sobrecargan el navegador y hacen que dispositivos menos potentes o con conexiones mucho menos rápidas y estables, tengan problemas para cargar las páginas más simples.

Para evitar esta moda, Google está haciendo un buen trabajo con las Web Vitals. Es bastante estricto y no es fácil lograr una puntuación de más del 90%. Además, los clientes se fijan en ese detalle y aunque no entiendan qué significan las distintas métricas, quieren que su página tenga una buena puntuación.

Con frameworks como Astro, que tienen esta arquitectura en su propio diseño, es casi imposible hacer una web lenta.

image 2
Astro y el test de PageSpeed

¿Y qué ocurre con el SEO?

Es fácil hacernos rápidamente esta pregunta cuando trasteamos con este tipo de frameworks tan nuevos, y más todavía si estamos acostumbrados a lidiar con aplicaciones SPA desarrolladas por ejemplo con Angular, que al no estar generadas en el servidor sino en el cliente, necesitan un router de URL’s adicional en el navegador, y hacer buen SEO es difícil.

En este caso, como el contenido está generado en el servidor, las páginas ya son de por sí SEO friendly. La misma arquitectura de islas favorece la buena indexación.

Frameworks con arquitectura de islas

Además de Astro, que es actualmente de los más conocidos y en cuestión de muy poco tiempo ha adquirido una popularidad asombrosa, también existe Marko, un framework open source creado por eBay y que soporta dicha arquitectura.

100% de PageSpeed y 0€ de hosting

Screenshot 2022 08 20 182931

Os voy a contar de qué forma gestiono mi web y blog con WordPress y a la vez me olvido de mantener un hosting, o un servidor VPS como llegué a tener en su día que, para una web tan simple como esta, menudo coñazo. Además, aprovecho y la exporto entera a un formato estático y consigo un 95-100% de PageSpeed. Antes de hacer esto tenía un 75%.

El truco, aunque no tiene mucho misterio, es usar un hosting de estáticos como Vercel, que es precisamente el que he elegido, y tener una forma fácil de exportar toda la web que a la vez necesito gestionar desde el mismo WordPress.

WordPress debe ejecutarse con PHP y MySQL, y en mi caso lo hago en local, con un repositorio en Github. Cuando actualizo la web con un nuevo post, exporto la página a ficheros estáticos y lo subo a otro repositorio.

Además de no pagar hosting, tener en producción una web no dinámica, te despreocupa de la seguridad, del rendimiento y de mantener actualizado WordPress y sus plugins. Aunque la versión que tengas en local esté llena de exploits, en realidad no importa en absoluto.

Exportar la web a ficheros estáticos

Para hacerlo utilizo el plugin gratuito Simply Static, que además, si os interesa, tiene una versión Pro que es capaz de conectarse a Vercel (entre otros) y hacer el deploy directamente de la web. En mi caso he elegido la gratuita.

image 8

En menos de dos minutos tienes generados todos los ficheros HTML, CSS y JS que puedes subir a cualquier hosting sin necesidad de PHP ni MySQL. El plugin te deja elegir entre exportar toda la carpeta en formato .zip o dejarla en el servidor.

image 9

Conectar el repositorio con Vercel

Vercel es una plataforma en la nube para publicar ficheros estáticos y funciones serverless. Permite hospedar proyectos con deploy instantaneo, escalado automático, y sin necesidad de configuración ni supervisión.

La verdad es que pude poner en marcha tanto esta web como la landing de UptimeHouse en menos de 10 minutos. Es suficiente con enlazar el repositorio de Github y rellenar 4 campos. Flipé porque es prácticamente todo automático.

image 11
Configuración del proyecto en Vercel
image 10
Estado del deploy de la web

Actualizaciones de la web

Mantener al día la web en producción es tan fácil como actualizar el repositorio que tienes conectado en Vercel, y este publicará automáticamente los cambios en producción después de hacer push.

Si necesitas hacer cambios constantes y a diario, posiblemente necesites algo que te ahorre el paso de exportar, subir los ficheros a mano al repositorio y hacer commits. La versión Pro debería solucionarte el problema, o también puedes crearte alguna automatización con n8n o similares.

PageSpeed

El mero hecho de publicar una web estática no significa que automáticamente vayas a tener una puntuación del 100% en PageSpeed, pero ayuda bastante. También tengo las DNS en Cloudflare con optimizaciones de rendimiento adicionales activadas.

Es imposible detallar aquí todo lo que debes hacer, pero se podría resumir en formarte bien sobre qué tener en cuenta para que una web sea rápida en carga de CSS, JavaScript, formatos de imagen, y todo el proceso de renderizado del DOM en el navegador. No copies y pegues código JavaScript sin saber qué estás haciendo. Ordena bien los ficheros y su orden de carga. Optimiza y comprime para producción. Por último, pasa el test en la web de PageSpeed y aplica uno a uno todos los consejos que te da para mejorar.

Psst!, y no pases el test solo en la portada, sino también en otras plantillas de la web. Google tiene en cuenta tu puntuación en cada URL, no solo en la home.

Screenshot 2022 08 20 182931
Test de PageSpeed en la portada
Screenshot 2022 08 20 184711
Test de PageSpeed en un post

Creando UptimeHouse, un SaaS para monitorizar webs: Parte 1

Screenshot 2022 08 19 142455 1

Tras mis andaduras con mis antiguas startups YoteConozco, Directo al Artista y StoryDevil, tenía ganas de montar un SaaS yo sólo, así aprovecho para ponerme al día con tecnologías que a veces, en mi día a día, no tengo oportunidad de usar.

Hace años que utilizo plataformas para monitorizar webs y que me ayudan a dos cosas: estar tranquilo sabiendo que mis páginas web y las de mis clientes están funcionando bien, y enterarme el primero cuando algo va mal para poder actuar.

Pensé que sería buena idea montar una utilidad online tipo SaaS, de pago por suscripción, para ofrecer este servicio a empresas y particulares que quieran tener controlados sus proyectos.

Mi idea es poder hacer un poco de «build in public», sin esconder nada, y explicar el proceso hasta el final. Suelo dar avances por Twitter, pero probaré a ir escribiendo pequeños artículos como este para documentar el proceso.

Bueno, volviendo al tema. Quiero que, como mínimo, UptimeHouse pueda ofrecerte:

  • Un dashboard donde, con un simple vistazo, puedas ver si todo está bien o algo comienza a fallar.
  • Envío de alertas si alguna web empieza a empeorar en rendimiento. Evitar la necesidad de ejecutar continuamente herramientas como PageSpeed o Lighthouse. Incluso cuando el sistema detecta que la web no responde, o tiene el certificado SSL a punto de caducar.
  • Una página de estado personalizada para tus clientes. Que ellos mismos tengan acceso a un reporte semanal, mensual o anual sobre el estado y el rendimiento de su proyecto. Incluso que puedan recibirlo por correo.

El stack técnico

Empecé el diseño de la arquitectura técnica y la parte visual. Me decanté por un stack de desarrollo basado en Laravel, React y Tailwind CSS. Tecnologías maduras para proyectos en producción, y que me han gustado desde el primer día.

Junto a Laravel, estoy usando Jetstream que me ayuda a tener una buena base para un entorno SaaS con un Dashboard y funcionalidades de usuario básicas ya incluidas. Incluso la autenticación con doble factor. Utilizo React junto a Inertia JS, que conecta el frontend con el backend de Laravel.

Así de fácil puedo activar la doble autenticación y tener controladas las sesiones del navegador.

Doble autenticación de Jetstream

Para el entorno de desarrollo, estoy usando Docker, y VS Code como IDE principal. Empecé con PhpStorm, que siempre me ha gustado, pero se me estaba haciendo algo pesado de configurar, actualizar y mantener sobre todo en los distintos entornos con los que suelo trabajar (sobremesa Windows y portátil macOS).

Ahora mismo tengo gran parte del frontend terminado y media API. Pronto empezaré a desarrollar los servicios de backend. También he publicado la landing en UptimeHouse.com para posicionar y captar correos de usuarios interesados en probar. Por cierto, aunque en la página he puesto precios, no es algo que tenga todavía muy claro y he cambiado bastante de opinión en estas últimas semanas, así que para nada es definitivo. 😅

La interfaz

Mi idea es ofrecer un dashboard simple, claro y elegante, desde donde ver el estado de todas las webs, y de cada una, tener acceso a más detalles como las DNS del dominio, el certificado SSL, o datos de las Core Web Vitals y medir el rendimiento de tu web.

Para todo el frontend de los componentes he usado Tailwind CSS. Un menú horizontal superior para las secciones básicas (de momento son el dashboard y la gestión de websites), y uno lateral que permite navegar por los distintos apartados de cada site.

Los iconos pertenecen a la librería Heroicons, en SVG, y puestos en el template via código JSX, y para los gráficos he utilizado Chart.js. Me ha parecido muy decenet y fácil de usar.

Y para acabar, ahí van algunas capturas. Lógicamente y en este punto, sujetas a cambios constantes según me levante.

El dashboard principal

Con un resumen de los principales monitores de cada web.

Dashboard de UptimeHouse

La sección Uptime

Datos básicos de la web, indicadores de si está online o no y estadísticas de varios periodos y posibles caídas.

Sección Uptime con resumen de caídas

Estadísticas de rendimiento

Con la puntuación del 0 al 100% sobre el rendimiento de tu web así como las Core Web Vitals.

image 3

Certificado SSL

Información detallada sobre el certificado de tu web. Aquí podrás ver si tiene algún problema y si se ha renovado correctamente.

image 6

Información sobre el dominio

Podrás consultar los Nameservers y las DNS de tu dominio, así como la fecha de renovación o actualización del mismo.

image 7

Aprender a programar con conceptos VS con ejemplos

pexels christina morillo 1181359

El otro día estaba viendo un directo del famoso streamer midudev, concretamente uno en el que simula una prueba técnica de React para Juniors. Por cierto, os recomiendo seguirle. Es un puto fenómeno.

Una de las cosas que más me llamó la atención es que ambos candidatos tenían problemas para inicializar el framework desde 0, sin copiar y pegar el código. No es fácil estar en directo ante centenares de personas y los nervios juegan malas pasadas, está claro.

Esto suele ocurrir porque en el día a día sueles centrarte en dividir las tareas en pequeños problemas, y acabas acostumbrándote a buscar la solución en Google para después copiar y pegar código de Stack Overflow. Esto les puede ocurrir a Juniors y incluso a Seniors. Somos capaces de resolver problemas sin entender qué cojones estamos haciendo. A mí me pasa muchas veces. A veces, lo importante es solucionar el problema cuanto antes, y ya.

Esta es una base de ejemplo que tiene toda aplicación React. Un simple «Hola mundo»:

import React from 'react';
import ReactDOM from 'react-dom';

function App(){
   return (
      <div>
         <h1>Hello world!</h1>
      </div>
    );
}
ReactDOM.render(<App/>, document.getElementById("root"));

Entonces, Midu les decía que en caso de duda podían consultar la documentación oficial, pero no buscar en Google. Y alguno seguía con ciertos problemas porque no sabía exactamente donde encontrar la solución.

  • ¿Sabían que para arrancar la aplicación debían importar la librería React?
  • ¿Para qué sirve ReactDOM?
  • ¿Qué función básica hace que React renderice toda la aplicación en el navegador?
  • ¿Qué parámetros necesita esa función?

Es lo más básico, el pilar de implementación de React. ¿Qué ocurre? Normalmente usamos scripts para montar estas aplicaciones en las que el código base ya está incluido. No nos paramos a pensar qué hace que todo esto funcione.

Preguntarnos el porqué de las cosas, por insignificantes que parezcan. Esto logrará que, a largo plazo, seamos más autónomos y sepamos solucionar problemas más complejos.

Cuanto más claros tengamos los conceptos básicos, más fácil nos será entender los más complejos. Nos costará más tiempo al principio, pero al final seremos más rápidos y el resultado será mejor.

El camino rápido: 2 días para hacer un clon de Instagram

Hay un montón de cursos en plataformas como Udemy o YouTube sobre prácticamente cualquier tecnología, y en lugar de aburrirte con los core concepts, te enseñan en base a ejemplos y pequeñas aplicaciones. Parece mucho más atractivo y ameno que 20 o 30 horas de videos y documentos aburridos. Y lo es, claro.

Recuerdo hacer uno hace mucho tiempo para aprender Swift. Se anunciaba como «¡Podrás hacer tu propio clon de Instagram!». Y como no, era de los más vendidos. Iluso de mí, me metí. Pude hacer 8 o 9 apps para iPhone, incluso un clon del Flappy Bird. A las pocas semanas empecé a desarrollar una app con mi socio Carles, y tenía la sensación de no saber nada. No sabía ni por dónde empezar.

No aprendí a hacer un clon de Instagram. Aprendí a montar el proyecto con Xcode, copiar y pegar 4 lineas, compilar y que funcione. Nada más.

El camino lento: 15 días leyendo documentación

Cuando decidí usar Laravel, React y Tailwind como stack para desarrollar UptimeHouse, lo primero no fue buscar otro cursillo basado en ejemplos ni tenía la intención de sacar un MVP en una semana. Pasé un par de ellas leyendo únicamente documentación oficial y probando por mi mismo.

Empecé a desarrollar y notaba que podía hacer prácticamente cualquier cosa acudiendo únicamente a la documentación oficial. Entendía los conceptos básicos de cada herramienta. Sigo usando StackOverflow para dudas y problemas más complejos, sí, pero tengo la sensación de tener claros los conceptos.

Al final, si tienes claros los conceptos, acabas antes consultando la documentación que pasándote un par de horas probando distintas soluciones en Stack Overflow.

Docs? : r/ProgrammerHumor
Via: Reddit

Mis soluciones a todos los ejercicios del bootcamp Full Stack Open 2021

Si te animas a seguir el curso Full Stack Open 2021 de la Universidad de Helsinki, podrás aprender y ponerte al día con lo último en React, Redux, Node.js, MongoDB, TypeScript, y un montón de módulos y utilidades muy usadas actualmente para el desarrollo web moderno en JavaScript.

Quisé actualizarme y empecé a hacerlo hace unos pocos meses. No puedo dejar de recomendarlo.

Os comparto todas mis soluciones que he colgado como repositorios públicos en GitHub.

Parte 1

  • Introducción a React
  • JavaScript
  • Estado del componente, controladores de eventos
  • Un estado más complejo, depurando aplicaciones React

https://github.com/mpampols/fullstackopen.part1

Parte 2

  • Renderizando una colección, módulos
  • Formularios
  • Obteniendo datos del servidor
  • Alterando datos en el servidor
  • Agregar estilos a la aplicación React

https://github.com/mpampols/fullstackopen.part2

Parte 3

  • Node.js y Express
  • Implementación de la aplicación en Internet
  • Guardando datos en MongoDB
  • Validación y ESLint

https://github.com/mpampols/fullstackopen.part3

Parte 4

  • Estructura de la aplicación backend, introducción a las pruebas
  • Probando el backend
  • Administración de usuarios
  • Autenticación de token

https://github.com/mpampols/fullstackopen.part4

Parte 5

  • Iniciar sesión en la interfaz
  • props.children y proptypes
  • Probando aplicaciones React
  • Pruebas de extremo a extremo

https://github.com/mpampols/fullstackopen.part5

Parte 6

  • Flux-architecture y Redux
  • Muchos reducers
  • Comunicarse con el servidor en una aplicación redux
  • conectar

https://github.com/mpampols/fullstackopen.part6

Parte 7

  • React-router
  • Hooks personalizados
  • Más sobre estilos
  • Webpack
  • Componentes de clases, varios
  • Ejercicios: ampliar la lista de blogs

https://github.com/mpampols/fullstackopen.part7

Parte 8

  • Servidor GraphQL
  • React y GraphQL
  • Administración de bases de datos y usuarios
  • Iniciar sesión y actualizar la caché
  • Fragmentos y suscripciones

https://github.com/mpampols/fullstackopen.part8

Los mejores plugins de Visual Studio Code para desarrollo web en 2021

ferenc almasi FHIdRVGets unsplash

Os voy a compartir los que son, en mi humilde opinión, los mejores y esenciales plugins de VSCode para desarrollo web. Son todos los que utilizo a diario y me van muy bien a mi.

Mi lista de indispensable es la siguiente:

GitLens

image 1

GitLens es una gozada. Si trabajas mucho con Git es casi imprescindible si quieres que te haga la vida un poco más fácil. Añade soporte de Git a Visual Studio Code y lo integra completamente en el IDE. Mira la web oficial para daros cuenta de todo lo que es capaz de hacer.

https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens

Current Line Blame
Por ejemplo, es capaz de mostrar un blame personalizable en cada línea.

Project Manager

image 2

Es normal trabajar con más de un proyecto. Esta extensión ayuda a que podamos acceder a ellos y cambiar de forma más ágil:

https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager


Live Server

image 3

Como su propio nombre indica, esta extensión creará un servidor local para poder trabajar con nuestro proyectos con la capacidad de «Live Reload»

https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer&ssr=false#overview


Auto Rename Tag

image 5

Una de mis favoritas. Simplemente cambia los nombres de los dos tags a la vez cuando renombramos uno. Parece que no, pero ahorra mucho tiempo.

https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag


Prettier

image 6

Otra de mis favoritas. Formatea el código automáticamente de prácticamente cualquier tipo. Ojo, porque es posible que tengáis que perfilar bien la configuración del plugin y puede que no os detecte del todo bien algún formato específico de plantilla.

Por suerte, es muy personalizable y tiene muchísima comunidad y usuarios, por lo que encontraréis solución a muchos problemas o dudas que os vayan surgiendo.

https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode


Docker

image 7

Esta extensión facilita el trabajo con proyectos que estén basados en contenedores de Docker. Entre muchas otras cosas, añade una barra lateral que muestra todas las imágenes, volúmenes, redes y contenedores.

https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker


JavaScript (ES6) Code Snippets

image 8

Esta extensión tiene snippets de código para JavaScript en sintaxis ES6. Soporta JavaScript y TypeScript.

Estos son unos cuantos que incluye:

image 12

https://marketplace.visualstudio.com/items?itemName=xabikos.JavaScriptSnippets


Visual Studio IntelliCode

image 9

Esta extensión oficial de Microsoft, añade funcionalidades de inteligencia artificial que nos ayudan a ser más productivos programando en Python, TypeScript, JavaScript y Java. Lo hace añadiendo IntelliSense basado en técnicas de Machine Learning.

https://marketplace.visualstudio.com/items?itemName=VisualStudioExptTeam.vscodeintellicode


Better Comments

image 10

Con Better Comments podremos crear comentarios más amigables en nuestro código.

Annotated code

https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments


Bracket Pair Colorizer

image 11

¡Casi me emociono cuando descubrí esta pequeña joya!

Pasamos más tiempo leyendo código que escribiendo, así que toda extensión que haga más fácil la lectura, bienvenida sea. Bracket Pair Colorizer colorea con el mismo color los pares de brackets que se corresponden. Eso logra que sea más fácil identificar a qué corresponde cada uno.

Screenshot

https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer

Repaso a 2020 y metas para 2021

2021

Aunque ha sido un año totalmente distinto a lo previsto, he de decir que no me ha ido del todo mal. Tengo la suerte de trabajar en un sector en auge y que además me apasiona. Pude seguir trabajando desde el primer día de confinamiento y he comprobado que tengo la cabeza lo suficientemente centrada como para, por lo menos, no haberme vuelto loco durante estos últimos meses. 😅

Tengo presente que hay que seguir trabajando muy duro pase lo que pase. Nos levantemos con malas noticias o con buenas. Da igual. Como dice Jack Butcher en este twit:

Mi resumen de lo más destacable de este 2020

  • Me compré una casa y me mudé.
  • Me he adaptado al teletrabajo.
  • Tengo salud, y he podido quedar y disfrutar con mis amigos algún que otro rato dentro de las limitaciones. Ellos dirán, pero creo que lo he conseguido.
  • He colaborado a que la empresa donde trabajo (ACTIUM Digital) crezca en equipo y proyectos.
  • He lanzado un nuevo proyecto junto a un amigo y excompañero de trabajo: Newslead. Ha quedado chulo. Nos gusta. Pero estamos estancados en crecimiento. De momento no ha recibido la acogida que esperábamos.
  • He lanzado nuevas funcionalidades en StoryDevil, una aplicación web que creé junto a mi amigo Carles Gòdia. También seguimos algo estancados y no hemos logrado el número de usuarios que nos habría gustado conseguir.
  • Me he leído un libro nuevo. Skin in the Game, de Nicholas Taleb. Mal porque quería terminar más.
  • He escrito más en mi blog. 19 artículos.
  • He renovado mi web.
  • He aprendido algún que otro framework nuevo, como React.
  • Me adapté al uso de teclados mecánicos TKL y empecé a aficionarme bastante al tema ⌨

Uno de los problemas con los que me encuentro tras lanzar nuevos proyectos como Newslead o StoryDevil, es que nos quedamos estancados en conseguir nuevos usuarios. No logramos crear una buena campaña de marketing, o quizá no sean productos lo suficientemente buenos o bien enfocados y no nos hemos dado cuenta. Francamente, no estoy seguro.

Para este 2021 quiero aprender más de estas situaciones y evitar que se repitan. No alargar agonías durante años como hice en un pasado con YoteConozco.com. Y si algo no funciona o no creo totalmente en un proyecto, quiero dejarlo rápidamente e ir a por otra cosa.

Aunque no soy fiel seguidor de las listas y me gusta improvisar un poco porque todo cambia, sí que tengo claros algunos puntos y objetivos para este 2021 que espero que sean la base para conseguir más cosas.

  • Exponerme a más riesgos de forma honesta, generar confianza y lograr beneficios por ello.
  • Publicar algún nuevo proyecto pequeño, rápido y quizá en solitario.
  • Colaborar para que la empresa donde trabajo crezca más y siga adaptándose a la época «post-COVID» que espero que llegue en algún momento de 2021.
  • Decidir qué hacemos con StoryDevil, o logramos muchos más usuarios o acabamos con él antes de fin de año.
  • Leer más y mejor. No por obligación sino porque realmente me gusta, pero he priorizado otras cosas. Entre hoy y mañana espero terminar The Almanack of Naval Ravikant
  • Aprovechar el jardín y la BBQ, y quedar todavía más con amigos. Pasar más tiempo con ellos y dejar claro que son una prioridad por delante de un simple proyecto o tarea pendiente.
  • Aprender o mejorar en:
    • Rust
    • JAMStack
    • TailwindCSS
    • Kubernetes
    • Vue
    • Laravel
    • … y el que me caiga en gracia en cualquier momento.
  • Fabricar un teclado mecánico lo más desde 0 posible. Poder divertirme con este hobby y no acabar arruinado 🤞

Cumple con la GDPR con este simple y elegante plugin de cookies gratuito

photo 1586195831749 9fc3b289b4e4

Estos días he dedicado unas cuantas horas a buscar y probar algunos plugins JavaScript de cookies para poder poner un aviso simple, limpio, gratuito, y que cumpla con la GDPR o RGPD.

He encontrado uno que me ha gustado y cumple con lo que necesito: Cookieconsent Script

Antes de nada os recomiendo dos cosas. Leer la Guía sobre el uso de las cookies de la Agencia Española de Protección de Datos (AEPD) y no tomaros al pié de la letra todo lo que os explicaré. He interpretado la ley con el mejor criterio posible pero no soy abogado ni experto en este sentido.

Image for post
Aviso de cookies de storydevil.com

Como se intuye en la captura, es un plugin simple, fácil de integrar, y con un diseño bastante elegante. Un módulo JavaScript genérico que puede adaptarse a cualquier proyecto web sin necesidad de hacerlo dentro de un CMS complejo. Basta con tener unas nociones básicas de frontend.

No tiene formato ‘cookie wall’ de los que obligan al usuario a elegir una opción para interactuar con la web (no es algo obligatorio). Muestra un aviso en el footer con la opción de aceptar las cookies para poder instalarlas, y un botón de ajustes para que el usuario pueda elegir las que quiera y las que no.

Esto es lo que muestra la opción de configuración:

Image for post
Configurador de cookies de storydevil.com

Podemos añadir categorías de servicios y las distintas cookies que usemos para que aparezcan todas en la ventana anterior.

Cada cookie puede ser configurada para que el usuario pueda o no desactivarla. Las cookies técnicas por ejemplo no deben ser opcionales. Y también podemos hacer que el selector de activado o desactivado aparezca por defecto como más nos interese.

Por ejemplo, en este caso podemos hacer opcionales las cookies de Google Analytics.

Estos son los distintos tipos de bloqueo que podemos configurar en la variable type, ya que no están documentados:

  • dynamic-script
  • script-tag
  • wrapped
  • localcookie

Con la expresión regular “/_ga.*/” podemos hacer que controle las dos cookies que en mi caso Google Analytics v4 añadía a la web. Una llamada “_ga” y otra “ga_P5…”

Estas no deberían instalarse si el usuario no lo desea, así que tenemos que probar bien la implementación con, por ejemplo, el inspector de Google Chrome, en el apartado Aplicación > Cookies.

Image for post

Así puedes crear tu primera API REST con Deno

deno js background

No es necesario explicar los pasos para instalarlo. Están muy bien descritos en la web oficial. Yo para este ejemplo he usado VS Code, para el que existe este plugin oficial.

¿Cómo es Deno?

Deno es muy parecido a Node, pero lo que intenta hacer es ser más bueno construyendo un runtime más seguro y corrigiendo los errores de base que tenía Node. Deno es seguro por defecto. Esto significa que no tiene acceso a tu disco duro, ni a tu red. Lo tendrá únicamente si tú se lo das. Node, en cambio, tiene acceso a prácticamente todo nada más instalarlo.

Por ejemplo, si seguimos la guía oficial y ejecutamos el primer comando, veremos que funciona sin problema.

deno run https://deno.land/std/examples/welcome.ts

Pero si lo hacemos con el ejemplo que viene a continuación:

import { serve } from "https://deno.land/[email protected]/http/server.ts";
const s = serve({ port: 8000 });

console.log("http://localhost:8000/");
for await (const req of s) {
  req.respond({ body: "Hello World\n" });
}

Nos encontraremos con un error de permisos de acceso a la red:

Compile file://welcome.ts
error: Uncaught PermissionDenied: network access to "0.0.0.0:8000", run again with the --allow-net flag
    at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
    at Object.sendSync ($deno$/ops/dispatch_json.ts:72:10)
    at Object.listen ($deno$/ops/net.ts:51:10)
    at listen ($deno$/net.ts:152:22)
    at serve (https://deno.land/[email protected]/http/server.ts:261:20)
    at file://welcome.ts:2:11

Esto sucede porque el primer ejemplo no necesita ningún tipo de acceso adicional para funcionar, pero el segundo necesita acceso a nuestra red. Deno, al tener seguridad por defecto, no nos permite hacerlo a no ser que le otorguemos permiso para ello.

En este ejemplo, basta con ejecutarlo con el parámetro –allow-net, y funcionará.

Lo mismo ocurre con los ficheros, en este caso necesitamos –allow-read

Crear una API con Deno

Qué mejor forma para empezar a jugar con Deno que creando nuestra primera API REST.

Con este pequeño tutorial voy a crear un array muy simple de películas y los 5 métodos para listar, buscar, crear, actualizar y eliminar elementos.

El primer paso es crear un fichero de arranque. En este caso app.ts. Lo primero será cargar Oak, un framework middleware para el servidor http de Deno. Oak está inspirado en Koa, un middleware para Node.js. Parece ser que siguen con el juego de palabras. Al final, nos ayuda a que escribir APIs sea más sencillo.

Es un ejemplo bastante sencillo que se explica prácticamente por si solo. El servidor escuchará por el puerto 4000 y cargará las rutas definidas en el fichero router.ts que veremos justo después. En el fichero ./api/controller.ts pondré la definición de las funciones para los distintos endpoints.

import { Application } from "https://deno.land/x/oak/mod.ts";
import router from "./router.ts";
import {
  getMovies,
  getMovie,
  createMovie,
  updateMovie,
  deleteMovie,
} from "./api/controller.ts";

const env = Deno.env.toObject();
const HOST = env.HOST || "127.0.0.1";
const PORT = env.PORT || 4000;

const app = new Application();

app.use(router.routes());
app.use(router.allowedMethods());

console.log(`API is listening on ${HOST}:${PORT}...`);
await app.listen(`${HOST}:${PORT}`);

Momento de definir las rutas en el fichero router.ts. Aquí importaremos también el Router de Oak y las definiciones que crearemos en el controller.ts

Instanciamos un Router y definimos las 5 rutas comentadas.

Método Función
getMovies Devuelve todas las películas
getMovie Devuelve una película a partir de un id
createMovie Crea una nueva película
updateMovie Actualiza una película ya existente
deleteMovie Elimina una película
import { Router } from "https://deno.land/x/oak/mod.ts";
import {
  getMovies,
  getMovie,
  createMovie,
  updateMovie,
  deleteMovie,
} from "./api/controller.ts";

const router = new Router();

router
  .get("/movies", getMovies)
  .get("/movie/:id", getMovie)
  .post("/movies", createMovie)
  .put("/movies/:id", updateMovie)
  .delete("/movies/:id", deleteMovie);

export default router;

Ahora es momento de crear el fichero controller.ts para definir los métodos de la API y el array con la base de datos de prueba.

interface Movie {
  id: string;
  title: string;
  rating: number;
}

Justo a continuación, creamos el array comentado:

/**
 * Sample array with movies
 */
let movies: Array<Movie> = [
  {
    id: "1",
    title: "TENET",
    rating: 10,
  },
  {
    id: "2",
    title: "No Time to Die",
    rating: 8,
  },
  {
    id: "3",
    title: "The Way Back",
    rating: 7,
  },
  {
    id: "4",
    title: "The Invisible Man",
    rating: 9,
  },
  {
    id: "5",
    title: "Onward",
    rating: 8,
  },
];

Y ahora los distintos métodos, empezando por el que lista todas las películas. Quedaría así de simple:

/**
 * Returns all the movies in database
 */
const getMovies = ({ response }: { response: any }) => {
  response.body = movies;
};

Vamos a por el siguiente, el encargado de devolver una película a partir de un ID que le podremos pasar por parámetro.

/**
 * Returns a movie by id
 */
const getMovie = ({
  params,
  response,
}: {
  params: { id: string };
  response: any;
}) => {
  const movie = movies.filter((movie) => movie.id == params.id)[0];
  if (movie) {
    response.status = 200;
    response.body = movie;
  } else {
    response.status = 404;
    response.body = { message: "404 Not found" };
  }
};

Si probamos a lanzar la petición con Postman, veremos que funciona.

image 12
Lanzamos la petición para un ID en concreto.

Le toca el turno al método createMovie para crear una película. El código es el siguiente:

/**
 * Creates a new movie
 */
const createMovie = async ({
  request,
  response,
}: {
  request: any;
  response: any;
}) => {
  const body = await request.body();
  const movie: Movie = body.value;
  movies.push(movie);
  response.body = { success: true, data: movie };
  response.status = 201;
};

Si lanzamos la petición de prueba, el servidor nos contestará con el mensaje programado.

image 14

Si a continuación lanzamos la petición para devolver todas las películas, veremos como aparece la nueva correctamente.

image 15

Es el turno del método updateMovie para actualizar una película. El código es:

/**
 * Updates an existing movie
 */
const updateMovie = async ({
  params,
  request,
  response,
}: {
  params: { id: string };
  request: any;
  response: any;
}) => {
  const movie = movies.filter((movie) => movie.id == params.id)[0];
  if (movie) {
    const body = await request.body();
    movie.title = body.value.title;
    movie.rating = body.value.rating;
    response.status = 200;
    response.body = {
      success: true,
      data: movies,
    };
  } else {
    response.status = 404;
    response.body = {
      success: false,
      message: "Movie not found",
    };
  }
};

Lanzamos la correspondiente petición PUT con Postman, y obtendremos la respuesta correcta.

image 17

Y para finalizar, solo nos queda el método deleteMovie que, en este caso, elimina una película a partir de un id. Lo que hago es utilizar el filter() para actualizar el array manteniendo todas las películas con id distinto al enviado.

/**
 * Deletes a movie by a given id
 */
const deleteMovie = ({
  params,
  response,
}: {
  params: { id: string };
  response: any;
}) => {
  movies = movies.filter((movie) => movie.id !== params.id);
  response.status = 200;
  response.body = { success: true, message: "Movie removed" };
};

Probamos con Postman…

image 19

Y efectivamente acaba de desaparecer la película con id = 1.

image 21

Puedes descargarte todo el código de este ejemplo en este repositorio de mi GitHub.

eCommerce y Google Analytics: Venderás mañana si sabes porqué lo haces (o no) hoy

photo 1563013544 824ae1b704d3 1

Este es el primero de una serie de artículos que escribiré en colaboración con Josep Maria Florista. Un gran compañero en ACTIUM Digital que se encarga del marketing digital en los proyectos propios y de nuestros clientes. Josep Maria y yo trabajamos codo con codo para que las partes de SEO y marketing digital corran acompañadas de la parte más técnica y de desarrollo de los proyectos web y eCommerce.

Por esta razón, hemos decidido aportar valor conjunto en forma de publicaciones en nuestros respectivos blogs personales, para aportar sobre un tema que nos ha causado más de un quebradero de cabeza en los últimos meses. La analítica en los eCommerce. Josep María se centra en este artículo en la parte de configuración y uso de Google Analytics y yo, en la parte más técnica así como los puntos a tener en cuenta para que todo funcione bien, las comprobaciones a realizar y los posibles errores que puedes encontrarte en el proceso.

El objetivo es eliminar errores y lograr que las transacciones se registren de la forma más exacta posible.

Saber porqué te compran (y porqué no)

¿Qué es más importante, conocer porqué un usuario no acaba comprando, o saber cuando sí lo hace? Ambas cosas. Llevas dos meses pensando en comprar esa chaqueta de 400€ que te encanta. La tienes en el carrito de la tienda .com. Decides finalizar el pedido porque, simplemente, has tenido un buen día. O te lo quitas de la cabeza porque crees que tu mujer te pone los cuernos. Somos impredecibles.

Para tomar decisiones necesitamos sacar conclusiones, y para esto necesitamos datos. Fiables y exactos. No solo el número de visitas, los clics y las páginas más visitadas. Con esto no hay suficiente. De hecho, quizá sean los datos más irrelevantes en una tienda eCommerce.

Explica Josep Maria Florista que Google Analytics se ha convertido en la herramienta indispensable para poder medir, controlar y monitorizar todo lo que sucede en nuestro site. Cuando analizamos una página web con Google Analytics nos centramos más en aspectos como qué páginas consultan, con qué dispositivos lo hacen, o desde qué fuentes nos visitan.

La gran mayoría de estos análisis se realizan sin tener un objetivo que deban alcanzar los usuarios, bien porque es una página informativa, un blog o una página que tenga una actividad comercial directa, como puede ser una empresa que ofrece servicios.

Pero… ¿Qué sucede con los eCommerce o tiendas online? Este tipo de proyectos sí tienen un claro objetivo en el que basaremos el funcionamiento de las mismas: las transacciones.

Google Analytics dispone de informes de comercio electrónico muy potentes donde podremos conocer, entre otras métricas:

  • El total de ingresos
  • La tasa de conversiòn
  • El total de transacciones
  • El valor medio del pedido
  • El listado de los productos más vendidos

Además de mostrar estos datos en todos los informes de Google Analytics, podremos analizarlos en base a la transacciones realizadas. Si tenemos un eCommerce, el uso de los informes de Comercio Electrónico es una herramienta indispensable para poder monitorizar toda la información de las transacciones y por consecuencia poder analizar y optimizarlo.

Saber captar datos (y que no se pierdan)

Para la obtención de esos datos, deben comunicarse el navegador del cliente, el servidor del eCommerce, y los módulos externos (TPV). Entre ellos y sin ninguna grieta. Todos repercuten directamente en las estadísticas de venta. Si uno falla, tendrás incongruencias en los datos.

Preparar un eCommerce para averiguar estos datos parece fácil hasta que lo intentas. Entonces, te das cuenta de que no se trata simplemente de añadir el código que te facilita Google Analytics. En un proceso de compra intervienen muchos factores técnicos que debes contemplar para que los datos de navegación y compra se registren correctamente. Si falla alguno de los componentes, tendrás ventas sin registrar.

50 ventas en la web, 48 en Analytics. ¿Qué ocurre?

Has ganado una venta, pero no sabrás porqué. En algún momento Google Analytics ha dejado de trazar al usuario, y puede que sea tu culpa (o no). Cabe la posibilidad de que el usuario tenga un bloqueador de anuncios o que haya desactivado manualmente las cookies de tu web. En cualquiera de estos casos, no será posible hacer un tracking correcto de la transacción si usamos Google Analytics integrado en el cliente. Es decir, con la librería Javascript. Para evitarlo podemos usar la integración server-side, pero dejaremos este tema para otro artículo.

A continuación, explicaré cómo configurar bien tu eCommerce para intentar que eso no ocurra. Considerar todos los escenarios y explicarte qué debes tener en cuenta para no perder información por el camino. Que los analistas de ventas tengan toda la información posible, y que el cliente sepa qué ocurre en cada transacción.

Paso 1: Configurar Google Analytics

Según cuenta Josep Maria, antes que nada debemos insertar el código de seguimiento en nuestro eCommerce, esta acción la podemos llevar a cabo mediantes plugins del CMS que utilice nuestra tienda online o con Google Tag Manager. Es importante asegurar que la etiqueta está insertada y se activa en todas las páginas de nuestro sitio web, podemos realizar la comprobación con la extensión para navegadores Google Tag Assistant.

Para poder visualizar los informes de Comercio Electrónico accederemos a la pestaña de Administración de Google Analytics y, en la columna Vistas entraremos en la Configuración de comercio electrónico para habilitarla.

Una vez activada nos aparecerá una nueva opción para Habilitar los informes de comercio electrónico mejorados, esta acción nos habilitará un nuevo informe en forma de funnel que nos permitirá analizar todo el proceso de compra de nuestra página: usuarios que acceden, visitas a productos, añadir productos a la cesta y realizar el checkout de compra. Para implementar el informe de comercio electrónico mejorado deberemos realizarlo a través de plugins del propio CMS o directamente con Google Tag Manager.

Magento, por ejemplo, permite configurarlo sin necesidad de instalar ningún otro módulo. Basta con seguir esta guía oficial.

Configuración de Google Analytics en Magento
Configuración de Google Analytics integrada en Magento 2

También podemos considerar el uso de plugins externos que añaden funcionalidades y análisis mucho más exhaustivos como la extensión Google Analytics Enhanced eCommerce UA GTM Tracking de Welt Pixel. Tiene una versión gratuita y una de pago. Con ambas podemos llegar a tener datos mucho más específicos que con la integración del Magento base, como por ejemplo el uso de cupones o los productos comparados.

Si usas WooCommerce, tienes el plugin gratuito WooCommerce Google Analytics que también integra las funcionalidades del Enhanced E-Commerce Analytics.

Otro tipo de informes que son de gran ayuda para identificar mejor el target de usuarios que acceden a nuestra página web son los informes demográficos y intereses. Estos informes son fáciles de activar, basta con acceder a la sección Audiencia > Datos demográficos e Intereses donde además podremos consultar toda esta información.

La gran mayoría de eCommerce utilizan una plataforma TPV externa para introducir los datos bancarios. Una vez verificada la compra, los usuarios accederán a la thank you page, página desde donde se envía el hit con toda la información de la compra hacia Google Analytics.

Si no realizamos ninguna configuración cuando accedamos al informe de Adquisición > Canales de captación, nos encontraremos que las ventas proceden de un referral que será en realidad la plataforma TPV, ya que ha sido el último punto de acceso a la página. Lo que ocurre es que de ser así perderemos la información real del acceso de los usuarios que han realizado una compra, así que deberemos omitir las páginas TPV como referrals de nuestra página web.

Esta acción la podemos llevar a cabo en la Administración de Google Analytics, en la columna de Propiedad > Configuración de la propiedad > Lista de exclusión de referencias. En este punto debemos excluir los dominios de los métodos de pago externos de nuestra página web como pueden ser sis.redsys.com o paypal.com.

Una vez hecho esto y activada la funcionalidad de eCommerce en Google Analytics, asegúrate de que las visitas entran en la web visualizando el estado en tiempo real del dashboard de GA.

Vista en tiempo real de visitas en Google Analytics
Vista en tiempo real de visitas en Google Analytics

Nos llegan las visitas a la web, bien!. Pero falta lo más importante, que lleguen los datos relacionados con el comportamiento dentro del propio eCommerce. Ahí es donde está la verdadera magia. Con los datos concretos de analítica eCommerce podremos saber qué ocurre desde que empieza el proceso de compra hasta que termina. Todo lo que nos lleva a conseguir más ventas en un futuro.

Primero, asegurate de que las opciones de eCommerce están activadas en tu cuenta de Google Analytics. Puedes encontrarlas en la sección de administración, y en «Ecommerce Settings»

Confirmación de ajustes para eCommerce en Google Analytics
Confirmación de ajustes para eCommerce en Google Analytics

Paso 2: Revisar el envío de datos a GA

Vamos a comprobar si todo lo hecho hasta el momento, funciona. En esta parte es muy importante que los equipos de marketing digital y los desarrolladores estén bien comunicados.

No hay mejor forma que probar con una compra lo más real posible. Prepara tu entorno de pruebas y todo lo necesario para completar una transacción. Es importante tener siempre un entorno de test disponible porque esta no será la única vez que necesites validar todo el proceso. En un software complejo, por muchos tests que tengas, todo puede fallar. Un eCommerce no es una web corporativa. Todo lo que ocurre durante un proceso de compra debe funcionar a la perfección. Una sola pieza que falle, y vas a perder dinero.

Prepara y documenta usuarios de prueba, una tarjeta de crédito e incluso cupones de descuento. Añade productos en el carrito con distintas cantidades y configuraciones. Puedes usar un generador online de datos falsos que incluye los que puedes llegar a necesitar. Selecciona un método de pago (y repite la prueba con todos los que tengas). Llega hasta el final. Y luego, haz también un pedido cancelado.

No es difícil preparar un plan de pruebas. Basta con un excel. Si tienes todo el plan documentado, te será fácil repetirlo una y otra vez. Además, podrás delegar la tarea. O mejor, automatizarla. Quiero hablar de esto en un futuro.

¿Cómo comprobar si llegan bien las compras?

Es la parte más fácil. Revisa Google Analytics y asegúrate de esto. Verás rápidamente si interpreta bien los datos del eCommerce.

Shopping Behavior Analysis de Google Analytics
Shopping Behavior Analysis de Google Analytics

No es así. ¿Qué hago?

Además de revisar la correcta configuración de Google Anaytics, debes revisar si realmente los datos se están enviando hacia los servidores de Google.

Para hacerlo, puedes usar el inspector de Chrome (o de tu otro navegador favorito) y analizar la petición enviada. Necesitas entrar en la pestanya Network, encargada de mostrar las peticiones de red, y filtrar por las que contienen «collect«. En el ejemplo de la captura, vemos una petición realizada haciendo clic en el botón de añadir producto en el carrito.

Pestaña Network del navegador Chrome para verificar el hit
Pestaña Network del navegador Chrome para verificar el hit

Paso 3: Confirmación del pago

Aunque parezca que no, esta es una de las partes más importantes. Es el paso final. Si Google Analytics no logra rastrear este paso, no se confirmará correctamenet tu venta.

A veces, la diferencia entre que sea fácil o difícil, es que el método de pago esté integrado en la web o sea un enlace externo. Podremos como ejemplo la pasarela estándar de Redsys. Esta integración puede realizarse de distintas formas. Si optamos por la más básica, el cliente saldrá de nuestra web para introducir los datos de su Visa y volverá al eCommerce cuando se confirme o cancele el pago. Aquí está el problema, que el usuario sale y tiene que volver para que Google Analytics lo sepa.

Cuando el usuario ha pagado, aparece esta pantalla. Si pulsamos continuar, volveremos al eCommerce y la venta se registrará. Si cerramos la ventana, no. ¡Ups!

Pantalla de confirmación de pago de Redsys
Pantalla de confirmación de pago de Redsys

Los métodos de pago (Redsys, Paypal, etc) tienen una URL de callback para avisarnos del resultado del pago y poder confirmar realmente la venta. Nos envían de forma cifrada los datos y el eCommerce puede validar el proceso. Esto suele ir en paralelo al tracking de Google Analytics, que se realiza en el cliente. Este segundo es el que puede perderse en el ejemplo anterior.

Hay dos formas de controlar esta parte. Garantizar el envío del tracking desde el servidor y no solo desde el cliente (porque lo hace via JavaScript) o bien configurar el TPV para que no pase por esta pantalla y evitar el maldito continuar. El tracking server-side merece un artículo dedicado, así que lo dejaré para más adelante.

Al grano. Debemos asegurar que Redsys no muestra esta pantalla y, en su lugar, redirige al cliente hacia nuestro eCommerce. Si evitamos este paso, aseguraremos que el cliente carga de vuelta nuestra web y podremos registrar la venta.

Desgraciadamente, Redsys implementa de forma distinta su TPV para cada banco, así que la opción de redirección no está siempre disponible. En muchos casos tendremos que avisar a Redsys para que realice la gestión. Estarán acostumbrados y encantados.

Un último detalle, si tu web utiliza Cloudflare, revisa también la configuración para que el callback de Redsys llegue sin problemas.

Paso 4: Probar, probar y probar

Modificaciones, plugins nuevos, cambios de última hora… Cuando modificamos nuestro eCommerce, todo puede fallar. Comprueba todo por duplicado, y prepara un plan de pruebas.

¿Qué puedo testear?

  • Compra de un producto
  • Compra de varios productos
  • Compra con un usuario registrado y otro anónimo
  • Prueba todos los métodos de pago
  • Compra de un producto con múltiples cantidades
  • Múltiples productos, múltiples cantidades
  • Añade productos al carrito desde las distintas páginas posibles (detalle, categoría, etc)
  • Compra con un total exacto (10.00€)
  • Compra más de 1.000€ (prueba los separadores de miles)
  • Compra productos con carácteres especiales en los nombres
  • Compra con descuentos
  • Compra utilizando la misma dirección como entrega y facturación (y al revés)

Contempla posibles errores

El usuario no siempre sigue el paso lógico de compra que testeas tu, así que comprueba también todos los posibles caminos y errores, como por ejemplo.

  • Refresca la pantalla de pago
  • Pulsa atrás en el navegador dentro de la pantalla de pago
  • Deja tu sesión inoperativa por 1 hora y luego continua con la compra

Queda claro que no es un tema nada fácil, verdad?