This episode covers authentication in Gatsby: client-side auth patterns, integrating Netlify Identity and Firebase Auth, protecting routes with client-only paths, and safe token storage and content rendering.

Some content really must be restricted: user dashboards, member areas, or drafts. Because Gatsby is static, protection happens on the client side with specific patterns — and we need to be honest about its security limits.
Episode 13 covers client-side auth patterns, integrating Netlify Identity and Firebase Auth, route protection, and safe token storage and content rendering.
All of the site's JavaScript and HTML is already delivered to the browser when the page loads. That means protecting a static page means holding back content from rendering until a user is proven logged in — not hiding files from the internet. For truly secret content, combine this with a serverless function on the server side.
The pattern used by almost all Gatsby sites: wrapRootElement provides the auth context across the whole app, then a guard component checks the login status before showing content.
Netlify Identity provides registration, login, and JWT tokens without a server. Install the two packages:
npm install gatsby-plugin-netlify-identityConfigure it in gatsby-config.js with your site URL:
module.exports = {
plugins: [
{
resolve: "gatsby-plugin-netlify-identity",
options: {
url: "https://situs-kalian.netlify.app",
},
},
],
}The auth provider must wrap the entire app via gatsby-browser.js:
import { NetlifyIdentityProvider } from "react-netlify-identity"
export const wrapRootElement = ({ element }) => (
<NetlifyIdentityProvider url="https://situs-kalian.netlify.app">
{element}
</NetlifyIdentityProvider>
)Gatsby runs wrapRootElement to wrap all pages. With the provider active, the useIdentityContext hook can be used in any component.
Member area pages should be handled as client-only routes. Install the supporting plugin:
npm install gatsby-plugin-create-client-pathsRegister it in gatsby-config.js with a URL pattern:
module.exports = {
plugins: [
{
resolve: "gatsby-plugin-create-client-paths",
options: { prefixes: ["/app/*"] },
},
],
}The /app/* prefix makes all pages beneath it fully handled on the client, which suits private dashboards.
A wrapper component checks the login status before rendering content:
import { navigate } from "gatsby"
import { useIdentityContext } from "react-netlify-identity"
const ProtectedRoute = ({ children }) => {
const { isLoggedIn } = useIdentityContext()
if (!isLoggedIn) {
navigate("/login")
return null
}
return children
}If isLoggedIn is false, the user is redirected to the login page and the content isn't rendered. This pattern is simple yet effective for gating the user experience.
The Identity plugin stores JWT tokens safely in localStorage and manages their refresh. For Auth0 integrations, @auth0/auth0-react handles storage the same way. The principle: let the library manage tokens — don't write your own risky token storage.
Secret content should never be rendered into static HTML. Since client-only paths and authentication run after mount, content only appears in the DOM after login — but this can still be read by users who know DevTools. For high confidentiality, pull data from a serverless function that validates the JWT on the server before returning data.
Auth0 provides the @auth0/auth0-react SDK. The pattern is the same: wrap the app with Auth0Provider, then use useAuth0 for the login status. It suits organizations that need SSO features and enterprise user management.
Firebase Authentication supports email, Google, and many other providers. With Firebase, besides authentication you can also manage users for free at large scale. Choose based on the ecosystem you're already using.
Episode 13 opened up authentication in Gatsby: client-side auth patterns, Netlify Identity integration, route protection with client-only paths, and safe token storage and rendering.
Key takeaways:
wrapRootElement wraps the app with an auth provider./app/* prefix for private pages.In the next episode, episode 14, we'll discuss API integration and caching — fetching APIs at build time and runtime, caching strategies for static sites, incremental builds, and reducing build time with selective sourcing.