Accessing Sanity singleton settings data in Next.js components (header/footer)

7 replies
Last updated: Nov 29, 2025
Hey y'all.I'm migrating an app from Gatsby to Next (using v13, and the
pages
directory) keeping Sanity as the CMS (of course).I have a
settings
document type (singleton) set up in my Studio with fields for site title, brand colors, social contact points etc...
My question is, what's the best way to access this data in a component, such as a header or footer?
The pervious Gatsby version used
useStaticQuery
in the header and footer components to get the settings data.
A bit of googling lead me to articles that suggest wrapping the app with React Context, and populating its initial state value with the
settings
data from a Sanity client fetch call? Then consuming the context on a component as needed.
Is this the best way to go about this?
Apologies if this is n00b question - I'd appreciate a bit of direction on how best to accomplish this.

♥️
AI Update

Using React Context is a solid approach for sharing your settings data across components in Next.js pages directory! This is actually a common pattern when migrating from Gatsby's useStaticQuery since the pages directory doesn't have a direct equivalent for component-level data fetching.

Here's what I'd recommend:

The Context Pattern (Your Instinct is Right!)

Fetch your settings data in _app.js and provide it via Context. This gives you similar ergonomics to what you had with useStaticQuery:

// pages/_app.js
import { createContext, useContext } from 'react';
import { client } from '../lib/sanity';

export const SettingsContext = createContext({});

export function useSettings() {
  return useContext(SettingsContext);
}

function MyApp({ Component, pageProps, settings }) {
  return (
    <SettingsContext.Provider value={settings}>
      <Component {...pageProps} />
    </SettingsContext.Provider>
  );
}

MyApp.getInitialProps = async () => {
  const settings = await client.fetch(`*[_type == "settings"][0]`);
  return { settings };
};

export default MyApp;

Then in your header/footer components:

import { useSettings } from '../pages/_app';

export function Header() {
  const { siteTitle, brandColors } = useSettings();
  return <header>{siteTitle}</header>;
}

Alternative: Fetch in Each Page

If you prefer keeping data fetching in getStaticProps, you can fetch settings alongside your page data and pass them to a Layout component as described in this approach to pulling global settings:

// pages/index.js
export async function getStaticProps() {
  const [pageData, settings] = await Promise.all([
    client.fetch(`*[_type == "page"][0]`),
    client.fetch(`*[_type == "settings"][0]`)
  ]);
  
  return {
    props: { pageData, settings },
    revalidate: 60 // Use ISR to keep settings fresh
  };
}

The Context approach is generally cleaner for truly global data like settings since you don't need to fetch and pass settings through every single page's getStaticProps.

Keeping Data Fresh

Since settings are fetched at build time, consider using Incremental Static Regeneration (ISR) with a revalidate value, or set up webhooks to trigger rebuilds when your settings change in Sanity Studio.

The React Context pattern you found is definitely a best practice for this use case in the pages directory! It's the closest equivalent to Gatsby's useStaticQuery for global data. Not a n00b question at all - this is a common migration challenge! ♥️

Show original thread
7 replies

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?