title: NextJS: Context values undefined in production (works fine in development)
body: <p>A &quot;dark mode&quot; feature has been implemented on my <code>Next.js</code> application using <code>React's Context api</code>.</p>
  <p>Everything works fine during development, however, <code>Context provider</code>-related problems have arisen on the built version — global states show as <code>undefined</code> and cannot be handled.</p>
  <hr />
  <p><code>_app.tsx</code> is wrapped with the <code>ThemeProvider</code> as such:</p>
  <pre><code>// React &amp; Next hooks
  import React, { useEffect } from &quot;react&quot;;
  import type { AppProps } from &quot;next/app&quot;;
  import { useRouter } from &quot;next/router&quot;;
  
  // Irrelevant imports
  
  // Global state management
  import { Provider } from &quot;react-redux&quot;;
  import store from &quot;../redux/store&quot;;
  import { AuthProvider } from &quot;../context/UserContext&quot;;
  import { ThemeProvider } from &quot;../context/ThemeContext&quot;;
  
  // Components
  import Layout from &quot;../components/Layout/Layout&quot;;
  import Footer from &quot;../components/Footer/Footer&quot;;
  
  // Irrelevant code
  
  function MyApp({ Component, pageProps }: AppProps) {
    const router = useRouter();
  
    // Applying different layouts depending on page
    switch (Component.name) {
      case &quot;HomePage&quot;:
        return (
          &lt;Provider store={store}&gt;
            &lt;ThemeProvider&gt;
              &lt;AuthProvider&gt;
                &lt;Component {...pageProps} /&gt;
                &lt;Footer color=&quot;fff&quot; /&gt;
              &lt;/AuthProvider&gt;
            &lt;/ThemeProvider&gt;
          &lt;/Provider&gt;
        );
      case &quot;PageNotFound&quot;:
        return (
          &lt;&gt;
            &lt;Component {...pageProps} /&gt;
            &lt;Footer color=&quot;#f2f2f5&quot; /&gt;
          &lt;/&gt;
        );
  
      default:
        // Irrelevant code
    }
  }
  export default MyApp;
  </code></pre>
  <p>The <code>ThemeContext</code> correctly exports both its <code>Provider</code> and <code>Context</code>:</p>
  <pre><code>import { createContext, ReactNode, useState, useEffect } from &quot;react&quot;;
  
  type themeContextType = {
    darkMode: boolean | null;
    toggleDarkMode: () =&gt; void;
  };
  
  type Props = {
    children: ReactNode;
  };
  
  // Checks for user's preference.
  const getPrefColorScheme = () =&gt; {
    return !window.matchMedia
      ? null
      : window.matchMedia(&quot;(prefers-color-scheme: dark)&quot;).matches;
  };
  
  // Gets previously stored theme if it exists.
  const getInitialMode = () =&gt; {
    const isReturningUser = &quot;dark-mode&quot; in localStorage; // Returns true if user already used the website.
    const savedMode = localStorage.getItem(&quot;dark-mode&quot;) === &quot;true&quot; ? true : false;
    const userPrefersDark = getPrefColorScheme(); // Gets user's colour preference.
  
    // If mode was saved ► return saved mode else get users general preference.
    return isReturningUser ? savedMode : userPrefersDark ? true : false;
  };
  
  export const ThemeContext = createContext&lt;themeContextType&gt;(
    {} as themeContextType
  );
  
  export const ThemeProvider = ({ children }: Props) =&gt; {
    // localStorage only exists on the browser (window), not on the server
    const [darkMode, setDarkMode] = useState&lt;boolean | null&gt;(null);
  
    // Getting theme from local storage upon first render
    useEffect(() =&gt; {
      setDarkMode(getInitialMode);
    }, []);
  
    // Prefered theme stored in local storage
    useEffect(() =&gt; {
      localStorage.setItem(&quot;dark-mode&quot;, JSON.stringify(darkMode));
    }, [darkMode]);
  
    const toggleDarkMode = () =&gt; {
      setDarkMode(!darkMode);
    };
  
    return (
      &lt;ThemeContext.Provider value={{ darkMode, toggleDarkMode }}&gt;
        {children}
      &lt;/ThemeContext.Provider&gt;
    );
  };
  </code></pre>
  <p>The <code>ThemeToggler</code> responsible for updating the <code>darkMode</code> state operates properly during development (theme toggled and correct value <code>console.log</code>ed upon clicking), however it doesn't do anything during production (<code>console.log</code>s an <code>undefined</code> state):</p>
  <pre><code>import React, { FC, useContext } from &quot;react&quot;;
  import { ThemeContext } from &quot;../../context/ThemeContext&quot;;
  
  const ThemeToggler: FC = () =&gt; {
    const { darkMode, toggleDarkMode } = useContext(ThemeContext);
  
    const toggleTheme = () =&gt; {
      console.log(darkMode) // &lt;--- darkMode is undefined during production
      toggleDarkMode();
    };
    return (
      &lt;div className=&quot;theme-toggler&quot;&gt;
        &lt;i
          className={`fas ${darkMode ? &quot;fa-sun&quot; : &quot;fa-moon&quot;}`}
          data-testid=&quot;dark-mode&quot;
          onClick={toggleTheme}
        &gt;&lt;/i&gt;
      &lt;/div&gt;
    );
  };
  
  export default ThemeToggler;
  </code></pre>
  <p>The solutions/suggestions I've looked up before posting this were to no avail.</p>
  <p><a href="https://stackoverflow.com/questions/60223841/react-context-api-undefined-in-production">React Context API undefined in production</a> — <code>react</code> and <code>react-dom</code> are on the same version.</p>
  <p>Thanks in advance.</p>
  <hr />
  <p>P.S. For those wondering why I am using both <code>Redux</code> and <code>Context</code> for global state management:</p>
  <ul>
  <li><p><code>Context</code> is best suited for low-frequency and simple state updates such as <em>themes</em> and <em>authentication</em>.</p>
  </li>
  <li><p><code>Redux</code> is better for high-frequency and complex state updates in addition to providing a better debugging tool — <code>Redux DevTools</code>.</p>
  </li>
  </ul>
  <p>P.S.2 Yes, it is better – performance-wise – to install FontAwesome's dependencies rather than use a CDN.</p>