Bonus
If you remember, we defined a logout helper function in our useAuth hook. We can implement that in the header.js component in our Gatsby project such that our header file will look like:
Further reading
If you want more information about authenticated areas with Gatsby, this (non-exhaustive list) may help:
Gatsby client only routes
First, we’re going to create a page in our ./src/pages/ folder called app.js which will import our components and use a helper from the @reach/router library to handle client only dynamic routing. Create the file in ./src/pages/app.js which will look like:
import React from "react"
import { Router } from "@reach/router"
import Layout from "../components/layout"
import Navigation from "../components/app/Navigation"
import Dashboard from "../components/app/Dashboard"
import Account from "../components/app/Account"
const App = ({ location }) => {
const redirect = location.pathname.split('/').pop()
return (
<Layout>
<Navigation />
<Router basepath="/app">
<Account path="/account" />
<Dashboard default />
</Router>
</Layout>
)
}
export default App
Gatsby wraprootelement
In order for all of our components in our app to become a context consumer we need to wrap our custom <AuthProvider> component around the gatsby root element. We created a helper functional wrapRootElement component in our useAuth.js file that exported our <
AuthProvider> component wrapped around the { element } prop that will be passed in to our wrapRootElement function. All we need to do now is use gatsby-browser.js to import (and immediately export) our wrapRootElement function. Open gatsby-browser.js in the project directory and add:
export { wrapRootElement } from './src/hooks/useAuth'
Implementing authentication in a gatsby site
There are a few things to be aware of when implementing authentication in a Gatsby site, because of how Gatsby uniquely builds pages and renders static assets with dynamic capabilities.
Installing gatsby project
We’re going to start with a new Gatsby project for our authentication tutorial. Creating a new project is easy with npx. We can open up our terminal and run the command:
gatsby new gatsby-authentication
Prerequisites
You should have already configured your environment to be able to use the gatsby-cli. A good starting point is the main tutorial.
Protecting code from accessing browser globals during build
Global objects that are accessible in the browser like localStorage aren’t available while a Gatsby site is building, because the build runs in a Node.js environment.
However, some third party services might try and access localStorage or the window object with internal methods. To keep those snippets from breaking the build, those invocations should be wrapped in checks or useEffect hooks to verify that the code is running in the browser and is skipped during the build process:
More information on build related errors is available in the guide on debugging HTML builds.
Real-world example: gatsby store
The Gatsby store is a live application built with Gatsby that implements authentication using Auth0.
Security notice
In production, you should use a tested and robust solution to handle the authentication. Auth0, Firebase, and Passport.js are good examples. This tutorial will only cover the authentication workflow, but you should take the security of your app as seriously as possible.
Understanding authentication between client and server
In many modern websites, the client — or frontend — is decoupled from the backend. This pattern is how Gatsby functions to combine data from a myriad of backend sources to facilitate building the frontend.
In order to provide authentication functionality, another service has to be leveraged and connected to Gatsby. There are many open source technologies than can provide this functionality. Examples include:
- A Node.js app using Passport.js
- A Ruby on Rails API using Devise
Another option are third party technologies like:
- Firebase
- Auth0
- AWS Amplify
- Netlify Identity