Overrides
Un override redirige la URL de una sola app solo para tu navegador,
persistido en una cookie. Ejecuta la app del carrito en localhost:5173
mientras el resto de la página carga desde producción; apunta una app a un
despliegue de preview para revisarlo en contexto.
import { override, removeOverride, getOverrides, clearOverrides } from 'wu-framework';Los overrides los aplica wu.init(), antes de registrar las apps: la URL
sobrescrita es la que queda registrada y aquella cuyo manifiesto se descarga.
Dónde viven los overrides
Sección titulada «Dónde viven los overrides»En cookies, una por app, con el nombre wu-override:<appName>:
wu-override:cart=http://localhost:5173Ni localStorage, ni un parámetro de consulta. Se eligieron cookies porque sobreviven a una recarga, son fáciles de establecer desde devtools y están acotadas al origen. Puedes poner una a mano sin ninguna API de Wu:
document.cookie = 'wu-override:cart=http://localhost:5173; path=/; max-age=86400';Cuándo están habilitados los overrides
Sección titulada «Cuándo están habilitados los overrides»Se habilitan automáticamente solo en hostnames locales:
| Hostname permitido |
|---|
localhost |
127.0.0.1 |
[::1] y ::1 |
0.0.0.0 |
cualquier cosa que acabe en .local |
cualquier cosa que acabe en .localhost |
Un puerto no estándar ya no cuenta como desarrollo. Antes de la v2.7 sí, lo
que habilitaba automáticamente los overrides en cualquier sitio de producción
servido tras un puerto como :8443. Combinado con el hecho de que una lista
allowedDomains vacía permite todos los dominios, un atacante capaz de escribir
una cookie podía apuntar una app a JavaScript arbitrario. El puerto no dice nada
sobre el entorno, así que la heurística desapareció.
Para habilitar overrides en cualquier otro sitio tienes que decirlo explícitamente:
await wu.init({ apps: [...], overrides: { enabled: true, allowedDomains: ['localhost', 'preview.example.com'], showIndicator: true, },});| Opción | Por defecto | Significado |
|---|---|---|
enabled |
detectado automáticamente del hostname | El valor explícito siempre gana, incluido un false en desarrollo. |
allowedDomains |
[] |
Hostnames a los que puede apuntar la URL de un override. Una lista vacía permite todos los dominios. |
showIndicator |
true |
Mostrar el banner fijo mientras haya algún override activo. |
Establece allowedDomains siempre que pongas enabled: true fuera de
localhost. El valor por defecto (lista vacía) es permisivo, y esa combinación es
exactamente de lo que iba el endurecimiento de la v2.7.
wu.override()
Sección titulada «wu.override()»override(appName: string, url: string, options?: { maxAge?: number; path?: string }): voidEstablece un override y escribe su cookie.
| Opción | Por defecto | Significado |
|---|---|---|
maxAge |
86400 (24 h) |
Vida de la cookie en segundos. 0 se respeta. |
path |
'/' |
Ruta de la cookie. |
wu.override('cart', 'http://localhost:5173');wu.override('header', 'https://preview-abc123.vercel.app', { maxAge: 3600 });location.reload(); // los overrides se aplican en init()Casos límite — esto lanza exactamente en cuatro situaciones:
| Condición | Mensaje |
|---|---|
Falta appName o url |
[WuOverrides] appName and url are required |
| Overrides deshabilitados aquí | [WuOverrides] Overrides are disabled in this environment. Enable with wu.init({ overrides: { enabled: true } }) |
| URL mal formada | [WuOverrides] Invalid URL: <url> |
Hostname no incluido en allowedDomains |
[WuOverrides] Domain not allowed: "<host>". Allowed: [...] |
Una URL válida es la que empieza por http://, https://, //, o la que
coincide con localhost seguido opcionalmente de un puerto. Ese último patrón
está anclado deliberadamente: de lo contrario localhost.evil.com pasaría como
una URL de localhost.
Ten en cuenta que establecer un override no afecta a una página que ya está
en marcha. Escribe la cookie; el wu.init() de la siguiente carga la aplica.
wu.removeOverride() y wu.clearOverrides()
Sección titulada «wu.removeOverride() y wu.clearOverrides()»removeOverride(appName: string): voidclearOverrides(): voidwu.removeOverride('cart');wu.clearOverrides();Casos límite. Ninguno lanza, y ambos funcionan incluso con los overrides deshabilitados. Eliminar una app que no tenía override se registra igual que si lo tuviera.
Un tropiezo real: removeOverride() caduca la cookie con un path=/ fijado en
el código. Un override establecido con un options.path personalizado no se
eliminará con él — tendrás que borrar esa cookie tú mismo.
wu.getOverrides()
Sección titulada «wu.getOverrides()»getOverrides(): Record<string, string>wu.getOverrides(); // { cart: 'http://localhost:5173' }Devuelve {} cuando no hay nada sobrescrito. Métodos relacionados en el
subsistema:
wu.overrides.getOverrideFor(appName): string | nullwu.overrides.hasOverrides(): booleanwu.overrides.isEnabled(): booleanwu.overrides.refresh(): voidwu.overrides.getStats(): objectrefresh() vuelve a analizar las cookies, que es lo que quieres tras editarlas
en devtools o en otra pestaña. getStats() informa de
{ enabled, activeOverrides, overrides, allowedDomains, showIndicator, environment }
— fíjate en que environment se recalcula a partir del hostname y por tanto es
independiente de enabled: puede decir production mientras los overrides
están activados explícitamente.
El banner indicador
Sección titulada «El banner indicador»Mientras haya algún override activo y showIndicator esté activado, un banner
ámbar fijo se sitúa en la parte inferior de la página:
WU OVERRIDE ACTIVE: cart → http://localhost:5173Existe por razones de antiphishing y anticonfusión: un override significa que parte de la página no es el código que crees, y un informe de QA presentado contra una página sobrescrita no vale nada sin ese contexto.
- Un clic oculta el banner. El override sigue activo.
- Doble clic llama a
clearOverrides().
Reglas de análisis de cookies
Sección titulada «Reglas de análisis de cookies»Las cookies mal formadas se omiten en lugar de ser fatales. Las entradas se
ignoran cuando el nombre o la URL están vacíos, y se avisa cuando la URL no es
válida ([WuOverrides] Invalid override URL for "<app>": <url>) o el dominio no
está permitido ([WuOverrides] BLOCKED: ...). Los valores de las cookies no
se decodifican como URL, así que una URL que contenga un % o un ; no
sobrevivirá a la ida y vuelta.
Limitaciones honestas
Sección titulada «Limitaciones honestas»- Solo en local, por diseño. Habilitar overrides en un hostname de
producción sin establecer
allowedDomainsrecrea la vulnerabilidad que eliminó la v2.7. - Requiere una recarga. Los overrides los aplica
init(), no el montaje. registerApp()los ignora. Una app registrada en tiempo de ejecución, después de queinit()ya se haya ejecutado, no recibe el override aplicado.removeOverride()asumepath=/. Las cookies con ruta personalizada le sobreviven.- Sin comodines ni patrones. Un override por nombre de app, coincidencia exacta.
- La cookie es entrada de confianza. Con una lista
allowedDomainsvacía, cualquier código o extensión capaz de escribir una cookie en tu origen puede redirigir una app a JavaScript arbitrario. EstableceallowedDomains.
