Does anyone have experience in saving a sanity fetch as global properties in next.js?

5 replies
Last updated: Nov 3, 2020
Does anyone have experience in saving a sanity fetch as global properties in next.js, which subsequently can be used for components such as a header, footer etc?
Thanks in advance
AI Update

Yes, this is a common pattern! There are a few solid approaches for handling global data like headers and footers in Next.js with Sanity.

With Next.js App Router, the best practice is to fetch your global data in your root layout (app/layout.tsx) and pass it down to your components. Since layouts are React Server Components by default, you can fetch data directly:

// app/layout.tsx
import { client } from '@/sanity/lib/client'

async function getGlobalData() {
  return await client.fetch(`{
    "header": *[_type == "siteSettings"][0].header,
    "footer": *[_type == "siteSettings"][0].footer
  }`)
}

export default async function RootLayout({ children }) {
  const globalData = await getGlobalData()
  
  return (
    <html>
      <body>
        <Header data={globalData.header} />
        {children}
        <Footer data={globalData.footer} />
      </body>
    </html>
  )
}

Alternative: React Context for deeply nested components

If you need the global data in many deeply nested components, you can create a Context Provider:

// app/providers.tsx
'use client'

import { createContext, useContext } from 'react'

const GlobalDataContext = createContext(null)

export function GlobalDataProvider({ children, data }) {
  return (
    <GlobalDataContext.Provider value={data}>
      {children}
    </GlobalDataContext.Provider>
  )
}

export const useGlobalData = () => useContext(GlobalDataContext)

Then wrap your app:

// app/layout.tsx
export default async function RootLayout({ children }) {
  const globalData = await getGlobalData()
  
  return (
    <html>
      <body>
        <GlobalDataProvider data={globalData}>
          <Header />
          {children}
          <Footer />
        </GlobalDataProvider>
      </body>
    </html>
  )
}

Important considerations

Don't fetch on the client side in components - As discussed in this community thread, fetching data client-side with useEffect will:

  • Hurt SEO (content won't be available to crawlers)
  • Count against your API limits on every page load
  • Cause slower initial renders

Caching - Remember that Next.js has its own caching layer. You can control revalidation with the revalidate export in your layout or use tag-based cache invalidation for more precise control.

Pages Router - If you're still using the Pages Router, you can fetch global data in _app.js using getInitialProps, though this disables automatic static optimization for all pages.

The layout approach is clean, performant, and follows Next.js best practices for server-side data fetching!

I think you should use reacts Context for this. Make a context provider and wrap your app in it. All page props then are reusable in its components. This will give you an idea:
_app.js

import { AppContext } from "./useAppContext";

function MyApp({ Component, pageProps }) {
  const { myGlobalProp } = pageProps;

  return (
    <AppContext.Provider value={{ myGlobalProp }}>
      <Component {...pageProps} />
    </AppContext.Provider>
  );
}

export default MyApp;
useAppContext.js

import { createContext, useContext } from "react";

export const AppContext = createContext(null);
export const useAppContext = () => useContext(AppContext);
myComponent.js

import { useAppContext } from "./useAppContext";

export const MyComponent = () => {
  const { myGlobalProp } = useAppContext();
  return <div>{ myGlobalProp }</div>
};
Yes. Did the fetch in getInitialProps located in _app.js (or ts). Added the result in pageProps and then added it as context
Nice thank you! I'll give it a try
user B
and
user B
- I know that i should insert my data fetched data into "value={{ myGlobalProp }}", so i can acces it globally - but can you tell me, if I'm supoosed to fetch the data from sanity in "useAppContext.js" or "_app.js"?
Hope , I'm not too much of a bother - thanks in advance.

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?