Reputation: 35
I want to set global SWRConfig just like: //_app.js file (next.js)
import '@/styles/bootstrap.min.css';import "@/styles/globals.css";
import Layout from "@/components/Layout";import { SWRConfig } from "swr";
export default function App({ Component, pageProps }) {
return (<>
<Layout>
<SWRConfig value={{fetcher: async (url) => {const res = await fetch(url);
// If the status code is not in the range 200-299,
// we still try to parse and throw it.
if (!res.ok) {
const error = new Error(
"An error occurred while fetching the data."
);
// Attach extra info to the error object.
error.info = await res.json();
error.status = res.status;
throw error;
}
return res.json();
},
}}
>
<Component {...pageProps} />
</SWRConfig>
</Layout>
</> );}
But I don't know how to do it in next.js 13 where the layout.js file in the app folder looks like this:
import './globals.css'import { Inter } from 'next/font/google'import Navbar from '@/components/Navbar';
const inter = Inter({ subsets: ['latin'] })
export const metadata = {title: 'Create Next App',description: 'Generated by create next app',}
export default function RootLayout({ children }) {return (
<html lang="en">
<body className={inter.className}><Navbar /><br />{children}</body>
</html>
)}
I tried wrapping the html part with <SWRConfig>...</SWRCongig>
but it didnt work and i am getting errors. I f i can setup a global fetcher using
<SWRConfigvalue={{fetcher: async (url) => {const res = await fetch(url);
if (!res.ok) {
const error = new Error(
"An error occurred while fetching the data."
);
error.info = await res.json();
error.status = res.status;
throw error;
}
return res.json();
},
}}
>
I would not have to write it again and again. Any help is appreciated.
Upvotes: 1
Views: 1448
Reputation: 342
<SWRConfig />
is based on React Context, which means it should be placed within a React Client Component.
Next.js Documentation offers extensive guidance on using React Context with the Next.js App Router: https://nextjs.org/docs/getting-started/react-essentials#context
In your case, try creating a new file app/context/swr-provider.js
:
// src/components/swr-provider.tsx
'use client';
export const MySWRProvider = ({ children }) => (
<SWRConfig value={{
fetcher: async (url) => {
const res = await fetch(URL);
// If the status code is not in the range 200-299,
// we still try to parse and throw it.
if (!res.ok) {
const error = new Error(
"An error occurred while fetching the data."
);
// Attach extra info to the error object.
error.info = await res.json();
error.status = res.status;
throw error;
}
return res.json();
},
}}>
{children}
</SWRConfig>
);
And in your app/layout.js
, import <MySWRProvider />
:
// app/layout.js
import './globals.css';
import { Inter } from 'next/font/google';
import Navbar from '@/components/Navbar';
const inter = Inter({ subsets: ['latin'] });
import { MySWRProvider } from './context/swr-provider.js'
export const metadata = { title: 'Create Next App', description: 'Generated by create next app', }
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>
{/** Here we wrap our app with <MySWRProvider /> */}
<MySWRProvider>
<Navbar />
<br />
{children}
</MySWRProvider>
</body>
</html>
)
}
Upvotes: 1