skip to Main Content

I want to use a headless CMO in my NextJs app (e.g. Sanity.io).
The content is especially important for SEO.
If I see it correctly, I can only receive the data on page-level via getStaticProps server-side to pre-render it that way (important for SEO).

If I now want to send the data from the page component to a deeply nested child, it’s awkward via prop drilling.
My first thought was to use React’s Context API (see code).

However, I suspect that during the build the state of the Context API does not take over the values (The SEO text for example).
So the pre-rendered page does not have the SEO content of the headless CMO.

Is there a way to send the values of the headless CMO to deeply nested children via getStaticProps without prop drilling? Or is the context API ok for this in terms of SEO / pre-render?

//pages/index.js

export default function Home({textFromGetStaticProps}) {
  const value = useAppContext();
  let {seotext, setSeotext} = value.content;

  console.log("The State is currently: " + seotext);
  console.log("The value of getStaticProps is currently:  " + textFromGetStaticProps);

//Can not set this in useEffect since only runs on ClientSide!
  setSeotext(() =>{
    console.log("---> setCount läuft");
    return textFromGetStaticProps;
  })

  return (
    <div className={styles.container}>
      <main className={styles.main}>
        <h1 className={styles.title}>
          The SEO Text is <a href="https://nextjs.org">{seotext}</a>
        </h1>
      </main>
    </div>
  )
}

//Fetch headless CMO Date via getStaticProps
export async function getStaticProps(context) {
  console.log("I am running Static Props");
  //API Fetch of headless CMO
  return {
    props: {textFromGetStaticProps: "SEO Text aus StaticProps"}, // will be passed to the page component as props
  }
}
//appContext.js
const AppContext = createContext();

export function AppWrapper({ children }) {
  const [seotext, setSeotext] = useState("SEO Text");
  const test = {seotext, setSeotext}
  console.log("I am Running AppContext: " + test);

  return (
    <AppContext.Provider value={{
      content: test,
    }}>
      {children}
    </AppContext.Provider>
  );
}

export function useAppContext() {
  return useContext(AppContext);
}
```

2

Answers


  1. There are a few ways to achieve this. The first that comes to mind would be to use something like the React Context API. However, you could also use something like Redux.

    Here is an example using the Context API:

    import React, { createContext, useContext, useState } from 'react';
    
    const AppContext = createContext();
    
    export function AppWrapper({ children }) {
      const [seotext, setSeotext] = useState("SEO Text");
    
      const test = {seotext, setSeotext}
      console.log("I am Running AppContext: " + test);
    
      return (
        <AppContext.Provider value={{
          content: test,
        }}>
          {children}
        </AppContext.Provider>
      );
    }
    
    export function useAppContext() {
      return useContext(AppContext);
    }
    
    Login or Signup to reply.
  2. Future versions of Next.js will make this much easier but in the meantime you could try using SWR or React Query to fetch data for pre-rendering and then query inside nested components.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search