Best way to access Sanity CMS data in a Next.js app using React Context or fetch query in route layout file.

7 replies
Last updated: Jan 18, 2023
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.

♥️
Jan 15, 2023, 3:01 PM
I actually have an app context just for an avatar.
We have a weird situation where we can't have one nav in a layout/document file so the nav is an individual component on every page. Nobody wants to see the image popping in and out reloading on every route change so I have it stored there in as a data URI and backed up behind that from localStorage.

How often do the values change?
Jan 15, 2023, 9:18 PM
Thanks for chiming in
user S
.The values shouldn’t change often, i think wrapping with an app context is probably my best bet here.

Although from what I’ve read since posting, if I move to using the /app directory features in Next 13, I could use a Sanity fetch query in a route layout file, and pass as props to a header / footer
as shown here .
Jan 15, 2023, 10:09 PM
Ah, yeah, based on my understanding from when the features debuted, I suppose that makes a lot of sense as well. I am actually behind the curve on the /app directory side of things. Lemme know how it goes!
Jan 16, 2023, 12:54 AM
Hey
user S
, do you have any code you can share with me showing how you implemented the app context as mentioned above?I've been playing around with wrapping the entire app in an
<AppContext.Provider>
(after reverting to using the
/pages
directory) - but I keep getting errors when trying to read values from the context?
Jan 18, 2023, 4:57 PM
I can't be super specific because of the nature of the project, but the broad steps I am using are• in _app import something called, say, ExampleProvider and wrap it around the page component just like any other JSX
• The file ExampleProvider exports a const equal to a null createContext and exports a function named, to extend the example, ExampleProvider which has as its only prop { children } destructured.
• Inside there's a useState pattern of variable and setter, and and it returns an actual context provider (the const I named earlier in the file) with a value prop set to both the value and setter, destructured
• On pages where I need to actively use it, I import ExampleProvider just as I did in _app
• Inside that page, I destructure the contents of it such that it matches the state setter inside the actual file being imported. For example:

import { createContext, useState } from "react";

export const ExampleContext = createContext(null);

export function ExampleContextProvider({ children }) {

  const [exampleData, setExampleData] = useState(YOUR_INITIAL_VALUES_HERE);

  return (
    <ExampleContext.Provider value={{ exampleData, setExampleData }}>
      {children}
    </ExampleContext.Provider>
  );
}
and then in a page


const { exampleData, setExampleData  } = useContext(ExampleContext)
so that I can both read the value, and also change it so that whatever I change it to is the 'new' thing-read-everywhere

In our case it's super necessary because I need the nav to only be a reader, but I need the profile page to change the picture so that there's an updated thing for it to always read
Jan 18, 2023, 5:47 PM
Thank you
user S
for the nice walkthrough here 👏 I've nearly got it working as originally planned.I appreciate the time you've taken to demo this example, it really helped me figure out where I was going wrong and breaking things
♥️
Jan 18, 2023, 8:41 PM
No problem Aaron!
When it comes to context and providers, I have literally copied off of people before and didn't understand what was going on right away.

It was so confusing that when it finally worked right I swore I just got lucky because I didn't catch what I did differently work actually work that time
🙂
Jan 18, 2023, 9:45 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?