El hook astro:config:setup
El hook más rico de la Integration API, el que abre el ciclo cuando la configuración todavía se puede cambiar. Qué recibe —config, command, isRestart, logger— y las utilidades que lo hacen poderoso: updateConfig para fundir cambios en la configuración sin pisarla, injectRoute para añadir rutas que no existen en src/pages, injectScript para colar código en cada página, addWatchFile para reaccionar a ficheros externos y addRenderer para enseñar a Astro un framework de UI.
Lo que recibe el hook y updateConfig
El hook recibe un objeto con varias piezas. config es la configuración resuelta hasta ese punto, de solo lectura para ti. command te dice bajo qué orden corre Astro —dev, build, preview o sync—, y sirve para actuar distinto según el caso. isRestart es un booleano cierto cuando el servidor de desarrollo se reinicia en caliente. Y logger es tu canal de mensajes, atribuido a tu integración. Pero la pieza que transforma es updateConfig.
'astro:config:setup': ({ config, command, updateConfig, logger }) => { logger.info(`corriendo bajo el comando ${command}`); updateConfig({ site: config.site ?? 'https://ejemplo.dev', vite: { ssr: { external: ['sharp'] } }, });},La regla de oro de updateConfig es que funde, no sustituye. Lo que pasas se combina en profundidad con la configuración existente: añadir un plugin de Vite no borra los demás, fijar una clave no aniquila sus hermanas. Nunca debes mutar config a mano —es un retrato del estado, no la palanca—; el único camino legítimo para cambiar la configuración es updateConfig, que además devuelve la config ya fundida por si necesitas leer el resultado.
El command que recibes junto a la config no es adorno: es lo que te permite comportarte distinto según por qué te llamen. Una integración de depuración que inyecta una barra de herramientas solo tiene sentido bajo dev y estorbaría en build; una que genera un fichero de manifiesto solo importa cuando hay build de verdad. Ramificar sobre command —actuar en dev, callarte en build, o al revés— es la forma idiomática de que tu integración no haga en un contexto lo que solo pertenece a otro. Leer esa pista al principio del hook y decidir a partir de ella es una marca de integraciones bien educadas.
injectRoute: rutas que no viven en src/pages
Una integración puede añadir páginas y endpoints que el usuario nunca escribió, y lo hace con injectRoute. Le das un pattern —la URL bajo la que vivirá— y un entrypoint —el módulo, normalmente dentro de tu paquete, que la renderiza—. Astro la trata como una ruta más, indistinguible de las de src/pages.
'astro:config:setup': ({ injectRoute }) => { injectRoute({ pattern: '/_estado', entrypoint: 'mi-integracion/paginas/estado.astro', prerender: false, });},Así es como una integración regala un panel de salud, una página de vista previa o un endpoint de webhook sin pedirle al usuario que copie ficheros. El pattern admite segmentos dinámicos igual que el enrutado normal; el entrypoint se resuelve como un import, así que suele ser una ruta de tu propio paquete. La opción prerender fija si esa ruta se hornea o se sirve bajo demanda, con independencia del resto del sitio.
injectScript: colar código en todas las páginas
Cuando tu integración necesita que cierto código corra en cada página —un script de analítica, un polyfill, una inicialización—, injectScript lo coloca sin que el usuario toque sus plantillas. Recibe dos argumentos: la etapa, que decide dónde y cómo se inyecta, y el código en sí.
'astro:config:setup': ({ injectScript }) => { injectScript('page-ssr', `import 'mi-integracion/registro.js';`);},Elegir la etapa es elegir el momento y el medio: head-inline para una etiqueta cruda en el head, before-hydration para lo que las islas necesitan antes de despertar, page para código de cliente empaquetado, page-ssr para lógica de servidor que corre en cada render. La etapa equivocada no falla ruidosamente; simplemente corre donde no querías.
addWatchFile y addRenderer
Dos utilidades más redondean el hook. addWatchFile le pide a Astro que vigile un fichero ajeno a src —un .env, un fichero de datos, la config de tu integración—, de modo que cuando ese fichero cambie, el servidor de desarrollo se reinicie y tu integración vuelva a correr con los datos frescos. Sin ella, un cambio en un fichero externo pasaría inadvertido.
'astro:config:setup': ({ addWatchFile }) => { addWatchFile(new URL('./datos.json', import.meta.url));},addRenderer, que ya viste al estudiar cómo se enrolan los frameworks de UI, registra un renderer con su serverEntrypoint y su clientEntrypoint. Es la utilidad que convierte a @astrojs/react o @astrojs/vue en lo que son. Rara vez la usarás salvo que escribas soporte para un framework nuevo, pero pertenece a este hook porque un renderer, como toda extensión, debe registrarse mientras la configuración aún es moldeable.
El hook guarda todavía un par de utilidades más especializadas que conviene conocer aunque las uses poco. addClientDirective registra una directiva de hidratación propia —una client: a tu medida, más allá de las que Astro trae— apuntando a un módulo que decide cuándo despertar la isla. Y addMiddleware, que verás en detalle en la próxima lección, inyecta un onRequest desde tu paquete. Todas comparten el mismo rasgo: solo existen aquí, en astro:config:setup, porque todas añaden algo al sistema y añadir solo es posible mientras la configuración sigue abierta.