Checklist de front-end para lanzar sin errores
Una lista de verificación previa al lanzamiento te ahorra los errores caros que solo se ven cuando ya están en producción.
Antes de poner un sitio en producción conviene pasar una lista ordenada por áreas, porque los errores que más cuestan (un sitio sin HTTPS, imágenes de 3 MB, formularios sin etiquetas) casi siempre se ven recién cuando ya está publicado y alguien se queja. Esta guía adapta al español la thedaviddias/Front-End-Checklist, un sistema open-source de calidad front-end, y la convierte en algo que podés correr de verdad antes de apretar deploy. Cada bloque de código es una caja para copiar: pegá la checklist en tu proyecto o pasásela a tu agente de IA para que la verifique por vos.
La idea no es marcar los 385 ítems del proyecto original. Es entender por qué importa cada cosa y quedarte con lo que aplica a tu caso. Empezá por lo crítico (lo que rompe el sitio o expone datos) y bajá desde ahí.
Head y metadatos
El <head> es lo primero que lee el navegador y casi nadie lo revisa. Si el charset está mal o falta el viewport, el sitio se rompe en mobile o muestra caracteres raros, y son tres líneas que arreglan todo.
Lo mínimo que no podés saltear:
charsetUTF-8 como primer elemento del head — si no, los acentos y la ñ salen rotos.viewport— sin esto el sitio se ve en miniatura en el celular, como si fuera una página de escritorio aplastada.- Doctype HTML5 en la primera línea del documento — activa el modo estándar del navegador.
langen el<html>— le dice a los lectores de pantalla y a Google en qué idioma está la página.- Título y
meta descriptionpor página — no genéricos, no repetidos. - Favicons para navegador y dispositivos.
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Título descriptivo y único de esta página</title>
<meta name="description" content="Resumen claro de 120-160 caracteres." />
<link rel="icon" href="/favicon.ico" sizes="any" />
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
</head>
</html>## Head — checklist - [ ] charset UTF-8 declarado como primer elemento del <head> - [ ] meta viewport para diseño responsive - [ ] doctype HTML5 en la primera línea - [ ] atributo lang en <html> con código de idioma válido (es, es-AR…) - [ ] título descriptivo y único por página - [ ] meta description por página (sin duplicados) - [ ] favicons para navegadores y dispositivos - [ ] Web App Manifest si querés que sea instalable (PWA)
HTML
HTML bien hecho es accesible, indexable y fácil de mantener casi gratis. Usá las etiquetas que el navegador ya entiende en vez de llenar todo de <div>.
- HTML semántico —
header,main,nav,section,article,footer. Le da estructura a la página para lectores de pantalla y buscadores sin que tengas que agregar nada. - IDs únicos — dos elementos con el mismo
idrompen el CSS, el JS y la accesibilidad. - Tipos de input correctos —
email,tel,number,search. En mobile abren el teclado adecuado y activan la validación del navegador. - Formularios con validación accesible — mensajes de error claros, asociados al campo, con los atributos ARIA correctos.
- Cargá los scripts con
defer,asyncotype="module"— así el JS no bloquea el armado de la página. - Página 404 propia con navegación útil, no la pantalla pelada del servidor.
- Sacá comentarios y código de debug antes de publicar.
## HTML — checklist - [ ] HTML semántico (header, nav, main, section, article, footer) - [ ] todos los id son únicos en el documento - [ ] type correcto en cada input (email, tel, number, search…) - [ ] formularios con validación y mensajes de error accesibles - [ ] scripts con defer / async / type="module" (no bloquean el render) - [ ] página 404 personalizada con navegación - [ ] sin comentarios ni console/debug en el HTML de producción - [ ] HTML validado contra los estándares del W3C
CSS
El CSS define cómo se ve y, si lo dejás crecer sin orden, termina siendo imposible de tocar sin romper algo. Apuntá a poco peso, especificidad baja y unidades que escalen.
- Evitá CSS inline y embebido salvo el CSS crítico — el resto va en archivos externos que el navegador cachea.
- Minificá y sacá el CSS que no se usa — menos bytes, render más rápido.
- No bloquees el render — cargá el CSS no crítico de forma asíncrona.
- Foco visible en todo lo interactivo — nunca borres el
outlinesin poner algo mejor; quien navega con teclado se pierde sin esa señal. - Custom properties para tus design tokens — colores, espaciados y tipografías como variables en
:root. Es lo que te habilita temas y modo oscuro sin duplicar todo. - Unidades relativas (
rem,em,%,clamp()) en vez depxfijos, para que el layout respete el tamaño de fuente del usuario. - Sin scroll horizontal y fuentes legibles en mobile — texto que se lee sin tener que hacer zoom.
- No desactives el pinch-zoom (
user-scalable=noestá prohibido): le saca a la gente con baja visión la posibilidad de agrandar. - Animá solo
transformyopacity— corren en la GPU a 60fps; animarwidth,topoleftgenera tirones.
## CSS — checklist - [ ] sin CSS inline/embebido (salvo el crítico) - [ ] CSS minificado y sin reglas muertas - [ ] CSS no crítico cargado sin bloquear el render - [ ] indicador de foco visible en todo lo interactivo - [ ] design tokens como custom properties en :root - [ ] unidades relativas (rem/em/%/clamp), no px fijos para layout - [ ] sin scroll horizontal en anchos estándar - [ ] tamaños de fuente legibles en mobile - [ ] pinch-zoom habilitado (sin user-scalable=no ni maximum-scale=1) - [ ] animaciones solo con transform y opacity
Imágenes
Las imágenes suelen ser el 80% del peso de una página. Una mal optimizada arruina el tiempo de carga más que cualquier otra cosa, así que es de lo primero que conviene mirar.
- Comprimí y serví formatos modernos (WebP o AVIF) con fallback — mismo resultado visual, mucho menos peso que JPEG/PNG.
widthyheightexplícitos en cada<img>— el navegador reserva el espacio y no se produce el salto de layout cuando carga la imagen (eso es el CLS).loading="lazy"en lo que está abajo del pliegue, para no descargarlo hasta que el usuario se acerque.- No uses lazy load en la imagen del hero — esa querés que cargue ya, con
fetchpriority="high", porque suele ser tu LCP. srcsetysizespara servir el tamaño justo según la pantalla — mandar una imagen de 2000px a un contenedor de 400px es tirar ancho de banda.altcon sentido en imágenes informativas;alt=""en las decorativas para que el lector de pantalla las ignore.
<img src="hero.webp" width="1200" height="630" alt="Descripción concreta de la imagen" fetchpriority="high" /> <img src="foto.webp" srcset="foto-480.webp 480w, foto-960.webp 960w, foto-1440.webp 1440w" sizes="(max-width: 600px) 100vw, 960px" width="960" height="540" alt="Descripción concreta" loading="lazy" />
## Imágenes — checklist - [ ] formatos modernos (WebP/AVIF) con fallback - [ ] imágenes comprimidas sin pérdida visible de calidad - [ ] width y height explícitos en cada <img> (evita layout shift) - [ ] loading="lazy" en imágenes fuera del viewport - [ ] hero SIN lazy load + fetchpriority="high" (es tu LCP) - [ ] srcset y sizes para servir el tamaño correcto por dispositivo - [ ] alt descriptivo en imágenes informativas; alt="" en decorativas - [ ] sin imágenes rotas (404)
Fuentes
Las fuentes web son fáciles de hacer mal: o el texto desaparece mientras cargan, o saltan de tamaño cuando llega la tipografía buena. Las dos cosas se notan y las dos se arreglan.
- WOFF2 como formato principal, con fallback — es el más liviano.
font-display: swappara que el texto se vea con la fuente del sistema mientras carga la tuya, en vez de quedar invisible.- Preload de la fuente crítica para que llegue antes y no haya salto.
- Definí un stack de fallback parecido a tu fuente final, así el cambio se nota lo menos posible.
@font-face {
font-family: "TuFuente";
src: url("/fonts/tufuente.woff2") format("woff2");
font-display: swap;
font-weight: 400;
}<link rel="preload" href="/fonts/tufuente.woff2" as="font" type="font/woff2" crossorigin />
## Fuentes — checklist - [ ] WOFF2 como formato principal (con fallback) - [ ] font-display: swap (el texto no queda invisible al cargar) - [ ] preload de la(s) fuente(s) crítica(s) - [ ] stack de fallback parecido para minimizar el salto de tipografía
JavaScript
El JS es donde más fácil se cuela un bug o un agujero de seguridad. Mantenelo prolijo, validá lo que entra de afuera y no dejes nada de debug en producción.
- Manejá los errores —
try/catchen lo asíncrono y error boundaries en los componentes, para que un fallo no tire toda la pantalla. - Nunca uses
eval()niinnerHTMLcon contenido que no controlás: es la puerta de entrada clásica a un XSS. - Validá los datos externos en runtime (con Zod o Valibot). Los tipos de TypeScript se borran al compilar y no te protegen de una respuesta de API con una forma inesperada.
constylet, nuncavar— evitás bugs de hoisting.- Code splitting — partí los bundles grandes con imports dinámicos para que la carga inicial sea liviana.
- Sacá los
console.logy todo el debug antes de publicar. - Debounce/throttle en eventos que se disparan mucho (scroll, resize, input).
## JavaScript — checklist - [ ] manejo de errores (try/catch en async, error boundaries en UI) - [ ] sin eval() ni innerHTML con contenido no confiable - [ ] datos externos validados en runtime (Zod/Valibot) - [ ] const/let en vez de var - [ ] code splitting / imports dinámicos para bundles grandes - [ ] sin console.log ni debug en producción - [ ] JS minificado - [ ] debounce/throttle en scroll, resize e input
Rendimiento
El rendimiento es retención: si tarda más de tres segundos en cargar, una parte de la gente ya se fue antes de ver nada. Google mide esto con los Core Web Vitals y lo usa para rankear.
Los números que importan:
- LCP (Largest Contentful Paint) bajo 2,5 s — cuánto tarda en aparecer el elemento más grande. Es la métrica crítica.
- CLS (Cumulative Layout Shift) bajo 0,1 — que no salte el contenido mientras carga. Se arregla casi todo poniendo
width/heighten imágenes y reservando espacio. - INP bajo 200 ms — que responda rápido cuando el usuario hace clic.
Las palancas que más mueven la aguja:
- Compresión de texto (Gzip o Brotli) y caché del navegador bien configurada.
- CDN para los assets estáticos — menos latencia.
- HTTP/2 o HTTP/3 para multiplexar requests.
- Lazy loading de lo que está abajo del pliegue y menos scripts de terceros (los analytics y los chats pesan).
- Peso total bajo 1500 KB, idealmente menos de 500 KB.
## Rendimiento — checklist - [ ] LCP < 2,5 s - [ ] CLS < 0,1 - [ ] INP < 200 ms - [ ] compresión de texto activada (Gzip/Brotli) - [ ] caché del navegador configurada (Cache-Control, ETag) - [ ] assets estáticos servidos desde CDN - [ ] HTTP/2 o HTTP/3 habilitado - [ ] lazy loading del contenido fuera del viewport - [ ] scripts de terceros cargados de forma asíncrona - [ ] peso total < 1500 KB (ideal < 500 KB)
Accesibilidad
Accesibilidad no es un extra: es que tu sitio funcione para todo el mundo, incluida la gente que navega con teclado o lector de pantalla. Buena parte se resuelve usando HTML correcto, y de paso te mejora el SEO.
- Todo navegable con teclado, en un orden de foco lógico que siga el orden visual.
- Labels asociadas a cada campo del formulario — sin esto, quien usa lector de pantalla no sabe qué va en cada input.
- Nombre accesible en botones e íconos — un botón que es solo un ícono necesita un
aria-label. - Contraste de color suficiente entre texto y fondo.
alten las imágenes (ya lo viste en Imágenes).- Link "saltar al contenido" para que el teclado se saltee el menú repetido.
- Foco manejado en modales — atrapado adentro, y que vuelva al disparador al cerrar.
- Nada que parpadee más de tres veces por segundo (riesgo de convulsiones).
<a href="#contenido" class="skip-link">Saltar al contenido</a> <button aria-label="Cerrar menú"> <svg aria-hidden="true"><!-- ícono --></svg> </button> <label for="email">Correo electrónico</label> <input id="email" type="email" name="email" autocomplete="email" />
## Accesibilidad — checklist - [ ] todo lo interactivo es navegable con teclado, en orden lógico - [ ] cada input tiene una label asociada - [ ] botones e íconos tienen nombre accesible (aria-label si hace falta) - [ ] contraste de color suficiente (WCAG AA) - [ ] alt en imágenes informativas - [ ] link "saltar al contenido" para teclado - [ ] foco atrapado en modales y devuelto al cerrar - [ ] nada que parpadee más de 3 veces por segundo
SEO
El SEO empieza en el front-end. Si Google no puede leer ni entender la página, no importa lo bueno que sea el contenido: no aparece. La mayoría son ítems simples que casi nadie revisa.
- Un solo
<h1>descriptivo por página, y jerarquía de headings ordenada (h1→h2→h3, sin saltarse niveles). - Título y
meta descriptioncon largo correcto y propios de cada página. - URL canónica para evitar contenido duplicado.
robots.txtysitemap.xmlpara guiar al crawler.- Open Graph y Twitter Cards para que el sitio se vea bien cuando lo comparten.
- URLs en minúscula, con guiones (no guiones bajos), descriptivas.
- Texto de los links descriptivo — nada de "hacé clic acá".
- Datos estructurados (JSON-LD) válidos si querés rich results.
<link rel="canonical" href="https://tusitio.com/pagina" /> <meta property="og:title" content="Título para compartir" /> <meta property="og:description" content="Descripción para redes." /> <meta property="og:image" content="https://tusitio.com/og.jpg" /> <meta name="twitter:card" content="summary_large_image" />
## SEO — checklist - [ ] un solo <h1> descriptivo por página - [ ] jerarquía de headings ordenada (sin saltar niveles) - [ ] título y meta description con largo correcto y únicos - [ ] URL canónica para evitar contenido duplicado - [ ] robots.txt y sitemap.xml presentes - [ ] Open Graph + Twitter Cards - [ ] URLs en minúscula, con guiones, descriptivas - [ ] texto de los links descriptivo (no "clic acá") - [ ] datos estructurados JSON-LD válidos (si aplica)
Seguridad
La seguridad del front no es opcional, y varios de estos ítems son críticos: si fallan, exponés a tus usuarios o quedás expuesto vos. Empezá por HTTPS y por no filtrar secretos.
- Todo el sitio por HTTPS, con redirección 301 de HTTP a HTTPS y header HSTS para forzar siempre conexión segura.
- Sin secretos en el cliente — nada de API keys, tokens ni contraseñas en el HTML o el bundle de JS. Esto es lo más crítico de la lista.
- Sin contenido mixto — una página HTTPS que carga recursos por HTTP rompe y el navegador te avisa.
rel="noopener noreferrer"en todo link contarget="_blank", para que la página que abrís no pueda manipular la tuya.- Content Security Policy (CSP) para frenar XSS y controlar de dónde se cargan los recursos.
- Headers de seguridad:
X-Content-Type-Options: nosniff,X-Frame-Options(anti-clickjacking),Referrer-Policy. - Tokens de sesión en cookies
HttpOnly+Secure+SameSite, no enlocalStorage(ahí los roba cualquier XSS). - Auditá las dependencias (
npm audit) por vulnerabilidades conocidas.
<a href="https://externo.com" target="_blank" rel="noopener noreferrer"> Enlace externo </a>
## Seguridad — checklist - [ ] todo el sitio por HTTPS (redirección 301 de HTTP → HTTPS) - [ ] header HSTS configurado - [ ] sin API keys, tokens ni secretos en HTML o JS del cliente - [ ] sin contenido mixto (nada cargado por HTTP en páginas HTTPS) - [ ] rel="noopener noreferrer" en links con target="_blank" - [ ] Content Security Policy (CSP) implementada - [ ] headers X-Content-Type-Options: nosniff y X-Frame-Options - [ ] tokens de sesión en cookies HttpOnly + Secure + SameSite - [ ] dependencias auditadas (npm audit) sin vulnerabilidades críticas
Extra: privacidad y testing antes de publicar
Dos áreas que el checklist original cubre y que conviene no saltear si tu sitio recibe datos o querés que aguante el paso del tiempo.
Privacidad (obligatorio si recolectás cualquier dato personal): política de privacidad linkeada desde el footer, aviso de consentimiento de cookies antes de poner cookies no esenciales, y pedí solo los datos que realmente necesitás.
Testing: probá en los navegadores principales (Chrome, Firefox, Safari, Edge) y en mobile real, no solo en el emulador. Si el proyecto va a crecer, sumá tests E2E (Playwright o Cypress) en los flujos críticos y monitoreo de errores en producción para enterarte de los problemas antes que los usuarios.
## Privacidad + testing — checklist - [ ] política de privacidad linkeada desde el footer (si recolectás datos) - [ ] aviso de consentimiento de cookies (antes de cookies no esenciales) - [ ] pedís solo los datos personales estrictamente necesarios - [ ] probado en Chrome, Firefox, Safari y Edge - [ ] probado en mobile real (no solo emulador) - [ ] tests E2E en flujos críticos (si el proyecto lo amerita) - [ ] monitoreo de errores en producción
Próximo paso
Agarrá tu sitio y pasale esta lista área por área, empezando por lo crítico: HTTPS, secretos, charset, viewport, labels e imágenes con dimensiones. Copiá los bloques que te sirvan a tu proyecto o pasáselos directo a tu agente de IA para que los verifique uno por uno mientras vos mirás el resultado.
Si querés que revisemos juntos tu sitio antes de lanzarlo y armemos una rutina de verificación a tu medida, agendá una llamada y lo vemos en vivo sobre tu código.
¿Querés implementar esto sobre tu caso real? Copiá la guía y pegala en tu agente — o trabajemos juntos.