Lab abierto

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

Filtrar por tag

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.

[SEO][Web Platform]

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.

[SEO][DevOps]

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.

[JavaScript][React][Web Platform]

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.

[pnpm][CI/CD][DevOps]

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.

[pnpm][DevOps]

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:.

[CSS][Accessibility][Web Platform]

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.

[JavaScript][Web Platform]

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.

[Laravel][PHP][Backend]

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.

[PHP][Backend]

@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+.

[CSS][Animation][Web Platform]

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.

[CSS][Web Platform][Performance]

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][Cache][Performance]

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.

[Next.js][Cache][Performance]

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.

[CSS][Design][Accessibility]

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.

[React][Next.js][Performance]

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.

[Tailwind][CSS]

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.

[Performance][Images][Next.js]

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.

[Next.js][Performance][Fonts]
RSS

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.