Shivam Sangwan
Shivam Sangwan

Reputation: 35

SWR Global Config

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

Answers (1)

Sukka
Sukka

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

Related Questions