Busca en todas las páginas de la documentación
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Instala SWR, envuelve tu app con SWRConfig y define valores predeterminados globales para que cada llamada a useSWR herede un fetcher compartido y opciones comunes.
npm install swr// app/providers.tsx
"use client";
import { SWRConfig } from "swr";
const fetcher = (url: string) => fetch(url).then((res) => res.json());
export function SWRProvider({ children }: { children: React.ReactNode }) {
return (
<SWRConfig
value={{
fetcher,
revalidateOnFocus: true,
dedupingInterval: 2000,
}}
>
{children}
</SWRConfig>
);
}// app/layout.tsx
import { SWRProvider } from "./providers";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<SWRProvider>{children}</SWRProvider>
</body>
</html>
);
}"use client";
import useSWR from "swr";
function UserProfile({ userId }: { userId: string }) {
// el fetcher se hereda de SWRConfig
const { data, error, isLoading } = useSWR(`/api/users/${userId}`);
if (isLoading) return <div>Cargando...</div>;
if (error) return <div>Error al cargar</div>;
return <div>¡Hola, {data.name}!</div>;
}SWRConfig usa React Context internamente para propagar valores de configuración por el árbol de componentes.useSWR sin un fetcher explícito recurrirá al fetcher del proveedor SWRConfig más cercano.SWRConfig; los valores internos se fusionan con los externos y los sobrescriben.dedupingInterval evita solicitudes duplicadas a la misma clave dentro de los milisegundos especificados.revalidateOnFocus provoca una revalidación en segundo plano cuando la pestaña del navegador recupera el foco.Fetcher personalizado con cabeceras:
const authedFetcher = (url: string) =>
fetch(url, {
headers: { Authorization: `Bearer ${getToken()}` },
}).then((res) => {
if (!res.ok) throw new Error("Error al obtener los datos");
return res.json();
});Sobrescritura de configuración anidada:
<SWRConfig value={{ fetcher: globalFetcher }}>
<SWRConfig value={{ refreshInterval: 3000 }}>
{/* Los componentes aquí obtienen globalFetcher + refresh de 3 s */}
</SWRConfig>
</SWRConfig>Configuración funcional (acceder al padre):
<SWRConfig
value={(parentConfig) => ({
...parentConfig,
refreshInterval: 5000,
})}
>
{children}
</SWRConfig>SWRConfig acepta value tipado como Partial<SWRConfiguration> o una función que devuelve uno.SWRConfiguration desde swr para tipar objetos de configuración de forma explícita.import type { SWRConfiguration } from "swr";
const config: SWRConfiguration = {
fetcher: (url: string) => fetch(url).then((r) => r.json()),
revalidateOnFocus: false,
};"use client" en el archivo del proveedor en Next.js App Router provocará un error en tiempo de ejecución porque SWRConfig usa React Context.error siempre será undefined, incluso en 404.dedupingInterval no es lo mismo que el almacenamiento en caché. Solo deduplica solicitudes en curso dentro de la ventana del intervalo.refreshInterval a nivel global se aplica a cada hook. Prefiere configurarlo por hook a menos que realmente necesites polling global.| Enfoque | Ventajas | Desventajas |
|---|---|---|
| SWRConfig global | Configuración única, valores predeterminados consistentes | Todos los hooks comparten la config; puede ser demasiado amplio |
| Config por hook | Control detallado por consulta | Declaraciones repetitivas del fetcher |
| Wrapper de hook personalizado | Lógica centralizada con flexibilidad | Capa de abstracción adicional |
SWRConfig usa React Context internamente, que es una API del lado del cliente. Sin "use client", Next.js trata el archivo como un Server Component y lanza un error en tiempo de ejecución cuando se usa Context.
useSWR con la misma clave dentro de esa ventana, solo se realiza una solicitud de red.Los valores del SWRConfig interno se fusionan con los externos y los sobrescriben. Por ejemplo, un proveedor interno puede definir refreshInterval mientras hereda el fetcher del proveedor externo.
SWR tratará la respuesta como datos exitosos. El valor error siempre será undefined, incluso en respuestas 404 o 500. Comprueba siempre res.ok en tu fetcher y lanza un error si es false.
Pasa una función en lugar de un objeto a la prop value:
<SWRConfig
value={(parentConfig) => ({
...parentConfig,
refreshInterval: 5000,
})}
>
{children}
</SWRConfig>Funciona, pero aplica polling a cada hook useSWR del árbol. Prefiere definir refreshInterval por hook a menos que realmente necesites que todas las consultas hagan polling a la misma frecuencia.
Importa SWRConfiguration desde swr y úsalo como tipo:
import type { SWRConfiguration } from "swr";
const config: SWRConfiguration = {
fetcher: (url: string) => fetch(url).then((r) => r.json()),
revalidateOnFocus: false,
};Acepta Partial<SWRConfiguration> o una función (parentConfig: SWRConfiguration) => SWRConfiguration que recibe la configuración del padre y devuelve una nueva.
Sí. Define un fetcher personalizado que incluya cabeceras:
const authedFetcher = (url: string) =>
fetch(url, {
headers: { Authorization: `Bearer ${getToken()}` },
}).then((res) => {
if (!res.ok) throw new Error("Error al obtener los datos");
return res.json();
});Si no hay un proveedor SWRConfig envolviendo el componente (o el proveedor no define un fetcher), useSWR no tendrá fetcher y nunca obtendrá datos en silencio. Asegúrate siempre de que exista un proveedor con fetcher por encima de tus componentes.
Envuélvelo alrededor de {children} en tu app/layout.tsx raíz para que cada página y componente herede la configuración compartida.
Revisado por Chris St. John·Última actualización: 19 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥