How to keep or resupply React Context in a Gatsby site

React Context is about providing some data to one or more child components without having to pass the data down through intermediary components. There's no built-in mechanism for persisting state between page loads, so you'll need to reach for another tool for that.

If you haven't already implemented your authentication layer, you'll want to look into how that will work. There are a number of strategies for maintaining that state, even just within using cookie-based storage. JWT (JSON Web Token) are a popular method that will let you store signed user and client-readable data in the cookie at the cost of requiring a bit more work to manage expiration/renewal and having a larger payload. Assuming that's the approach you took, you might do something like this:

import React from "react";
import jwt from "jsonwebtoken"; // Add jsonwebtoken via npm/yarn

function getCookieValue(a) {
  var b = document.cookie.match('(^|[^;]+)\\s*' + a + '\\s*=\\s*([^;]+)');
  return b ? b.pop() : '';
}

const AUTH_PUBLIC_KEY = "your JWT public key here"

export const AuthContext = React.createContext();

export class AuthContextProvider extends React.Component {
  state = {
    authenticated: false,
    userid: null,
  };

  componentDidMount() {
    jwt.verify(getCookieValue("session"), AUTH_PUBLIC_KEY, (err, session) => {
      if (!err && session.userid) {
        this.setState({ userid: session.userid, authenticated: true })
      }
    })
  }

  // Important: REMOVE THIS AFTER TESTING/DEV
  toggleLogin = () => {
    this.setState(state => ({
      authenticated: !state.authenticated,
      userid: 2,
    }));
  }

  render() {
    return (
      <AuthContext.Provider
        value={{
          ...this.state,
          toggleLogin: this.toggleLogin,
        }}
      >
        {this.props.children}
      </AuthContext.Provider>
    );
  }
}

This will parse the JWT token in the session cookie when the AuthContextProvider is mounted and update the state with the userid value stored in the JWT if one is present.

You will probably want to wrap the Gatsby App with this component, which you can do from gatsby-browser.js and gatsby-ssr.js files (create them in the root of your repo if you don't have them yet):

// gatsby-browser.js
import React from "react"
import AuthContextProvider from "components/AuthContextProvider"

export const wrapRootElement = ({ element }) =>
  <AuthContextProvider>{element}</AuthContextProvider>

// gatsby-ssr.js
import React from "react"
export { wrapRootElement } from "./gatsby-browser"

You will still need to handle generating the JWT token (probably from a backend that is handling authentication) and if it's not already being persisted in a cookie you can access from the browser you will need to handle creation of that cookie at the relevant point in your application lifecycle.