Lo que voy aprendiendo.
Aprendizajes breves, gotchas y notas del día a día en desarrollo web. Patrones de Laravel, React, Next.js y más.
Notas
18 entradas
IndexNow no acelera la indexación en Google
Es el malentendido del protocolo: se implementa creyendo que avisa a Google, y Google no lo usa. Mueve Bing, Yandex, Seznam y Naver. Para Google el canal sigue siendo el sitemap con su lastmod y la inspección de URL en Search Console. Tampoco son 100 URLs al día, otro número que se repite: acepta 10.000 por POST y no publica cuota diaria.
La URL que más necesitas reenviar a IndexNow es la que acabas de borrar
Al consolidar dos posts en uno, la que hay que reenviar es la vieja: es la única forma de que el motor la rastree y vea el redirect. Y es justo la que ningún script te va a dar, porque la lista suele derivarse del directorio de contenido y esa carpeta ya no existe. Hay que pasarla a mano. Segunda trampa del mismo día: enviar antes de que el deploy salga hace que el motor revalide y reconfirme la versión vieja.
requestAnimationFrame no dispara en pestañas de fondo
Un aviso que se muestra con requestAnimationFrame dentro de un useEffect no aparece nunca si la pestaña se abrió en segundo plano: el navegador pausa rAF en documentos no visibles y lo reanuda recién cuando los miras. Si el rAF solo estaba para diferir un setState un tick y evitar el cascading-render, setTimeout(fn, 0) hace lo mismo y sí corre sin foco.
pnpm 10 en CI ignora en silencio los ajustes de pnpm 11
allowBuilds y minimumReleaseAge viven solo en pnpm-workspace.yaml y solo los lee pnpm 11; el campo pnpm de package.json ya no sirve para esto. Si el runner sigue en pnpm/action-setup con version: 10 no falla nada: los ignora sin avisar, así que esbuild se queda sin su postinstall y Vitest sin transformador, con un error que no apunta a la causa.
minimumReleaseAgeExclude de pnpm acumula en vez de reemplazar
pnpm 11 trae minimumReleaseAge en 1440 minutos por defecto, así que rechaza cualquier versión publicada hace menos de un día. Al forzar la instalación añade la excepción sola a minimumReleaseAgeExclude, pero la acumula sobre la entrada vieja en lugar de sustituirla: queda next@16.2.12 || 16.3.0 aunque la 16.2.12 ya no se instale. Solo hacen falta mientras la versión está dentro del corte, así que conviene podarlas.
Chrome pinta el anillo de foco de un SVG en :focus, no en :focus-visible
Un <path tabindex="0"> enfocado con un clic da :focus pero no :focus-visible, y aun así Chrome le pinta outline: auto. Con <button>, <a> o un <div tabindex="0"> no pasa. El reset va en :focus { outline: none }, no en :focus-visible; en Tailwind, la variante focus: y no focus-visible:.
new Date() parsea la fecha sin hora como UTC y con hora como local
new Date('2026-08-01') es medianoche UTC, pero new Date('2026-08-01T00:00:00') es medianoche local: añadir la hora cambia la zona. Si encima formateas con Intl sin fijar timeZone, la fecha sin hora retrocede un día en cualquier zona al oeste de UTC.
Laravel 13: Context::add() comparte datos entre middlewares y jobs
El nuevo helper Context en Laravel 13 permite pasar metadata a lo largo del request sin pasar parámetros. Útil para tracing: Context::add('request_id', $id) en un middleware y luego Context::get('request_id') desde cualquier job en cola. Persiste automáticamente al despachar jobs.
PHP 8.4: Property hooks reemplazan getters y setters
PHP 8.4 introduce property hooks nativos. En vez de definir getName() y setName(), escribes public string $name { get => ucfirst($this->_name); set => $this->_name = trim($value); }. Menos boilerplate y API más limpia para value objects y DTOs.
@starting-style permite animar elementos al aparecer en el DOM
La regla CSS @starting-style define el estado inicial de un elemento antes de la primera renderización. Útil para animaciones de entry sin JS: define los valores iniciales dentro de @starting-style { ... } y los finales en la regla normal. Soportado en Chrome 117+ y Safari 17.5+.
View Transitions API funciona cross-document en Chrome 126+
Las View Transitions ya no son solo para SPAs. Con @view-transition { navigation: auto; } en el CSS, Chrome 126+ aplica transiciones automáticas entre navegaciones MPA. Esto significa transiciones suaves en sitios estáticos sin necesidad de un framework JS.
Next.js 16: 'use cache' + cacheLife() reemplaza configuración fetch
Con Cache Components habilitado, marcar una función con 'use cache' y opcionalmente cacheLife('hours') reemplaza el viejo fetch(url, { next: { revalidate } }). Más declarativo y funciona con cualquier fuente de datos, no solo fetch. PPR genera shells estáticos + streaming dinámico.
Next.js revalidateTag() requiere expire: 0 para invalidación inmediata
Descubrí que revalidateTag(tag) en Next.js 16 no invalida inmediatamente por defecto. Debes usar revalidateTag(tag, { expire: 0 }) para forzar invalidación inmediata del cache. Esto es crítico para webhooks de revalidación.
OKLCH es superior a HSL para dark mode
OKLCH (color space) mantiene la percepción de brillo constante entre colores, a diferencia de HSL. Esto significa que un color con L=0.5 en OKLCH se verá igualmente brillante que cualquier otro color con L=0.5, perfecto para sistemas de diseño consistentes en dark mode.
React.cache() deduplica requests en Server Components
Usar cache() de React en funciones de data fetching en Next.js App Router deduplica automáticamente requests idénticos durante el mismo render tree. Ejemplo: si 3 componentes llaman a getPost('slug-123'), solo se ejecuta 1 request.
Tailwind @theme inline reemplaza extend en v4
En Tailwind CSS v4, @theme inline es la nueva forma de extender el tema. Reemplaza theme: { extend: {} } de v3. Mejora el performance del build y permite CSS variables nativas.
AVIF reduce imágenes 50% vs WebP
AVIF logra la misma calidad visual que WebP con ~50% menos tamaño de archivo. Para Next.js, configurar formats: ['image/avif', 'image/webp'] como fallback es la mejor estrategia. Safari soporta AVIF desde v16.4.
adjustFontFallback previene CLS en font loading
Next.js tiene adjustFontFallback: true en next/font que ajusta métricas del fallback font para match el custom font, previniendo layout shift (CLS) durante la carga. Crítico para Core Web Vitals.
No te pierdas ningún aprendizaje.
Los TIL tienen su propio feed, separado del de artículos, para que puedas seguir solo estas notas breves si es lo que te interesa.