developers

Adding Google Login to a React App with Auth0

Add Google login to a React app with Auth0. A step-by-step tutorial from installing the Auth0 React SDK to configuring your own production Google credentials.

Most users won't create a new account if they can reuse an existing one instead. Google login is usually the lowest-friction option you can offer, and adding it with Auth0 means you're not implementing OAuth yourself. Auth0 handles the redirect dance with Google, validates the tokens, and hands you back a user object. You wire it into React, and that's it.

This post covers everything from install to production-ready credentials, so let's get into it.

Prerequisites

  • A React app (this tutorial uses Vite)
  • An Auth0 account (the free tier works for everything here)
  • Node.js installed

Install the Auth0 React SDK

npm install @auth0/auth0-react

The SDK gives you a context provider and a useAuth0 hook that exposes authentication state and actions to any component in your tree. All the token handling, session management, and redirect logic lives inside it.

Create the Auth0 Application

In Auth0, an Application is the configuration record that ties your front-end to your tenant. It tells Auth0 which app is making authentication requests, which URLs it's allowed to redirect to, and how to encode the tokens it issues. You need one before the SDK can do anything.

In your Auth0 Dashboard, go to Applications and click Create Application. Name it, select Single Page Web Applications, and click Create.

Open Settings and scroll down to Show Advanced Settings, then the OAuth tab. Confirm that JsonWebToken Signature Algorithm is set to RS256 and OIDC Conformant is enabled. Both are on by default for new apps, but worth checking before you move on.

Still in Settings, find Application URIs and fill in all three fields with your local URL:

  • Allowed Callback URLs: http://localhost:5173
  • Allowed Logout URLs: http://localhost:5173
  • Allowed Web Origins: http://localhost:5173

This tutorial assumes Vite’s default development URL, http://localhost:5173. If you run Vite on another port, register that exact origin in Auth0 instead.

The callback URL is where Auth0 sends the user after a successful login, carrying the authorization code. The logout URL is where Auth0 redirects after you call logout(). Allowed Web Origins permits the browser-based SDK to make certain Auth0 requests from your application’s origin, including session and silent-authentication-related flows. Auth0 validates all of them against a strict allowlist, and if the URL in a request doesn't match exactly, it rejects it.

Before you leave this page, scroll up to Basic Information and copy your Domain and Client ID. You'll need both in the next step.

Wrap the App in Auth0Provider

Auth0Provider sets up a React context that makes authentication state available to every component in your tree. You put it at the root so that any component anywhere in your app can call useAuth0() and get the current user, loading state, or auth functions without prop drilling.

Open src/main.jsx and wrap your app:

import React from 'react';
import { createRoot } from 'react-dom/client';
import { Auth0Provider } from '@auth0/auth0-react';
import App from './App';

const root = createRoot(document.getElementById('root'));

root.render(
  <Auth0Provider
    domain={import.meta.env.VITE_AUTH0_DOMAIN}
    clientId={import.meta.env.VITE_AUTH0_CLIENT_ID}
    authorizationParams={{
      redirect_uri: window.location.origin,
    }}
  >
    <App />
  </Auth0Provider>
);

domain and clientId come from that Basic Information section. redirect_uri needs to match one of the callback URLs you registered, window.location.origin resolves to http://localhost:5173 in development, so it'll match what you just entered. Store the credentials in a .env.local file rather than hardcoding them:

# .env.local
VITE_AUTH0_DOMAIN=your-tenant.auth0.com
VITE_AUTH0_CLIENT_ID=your-client-id

Restart the Vite development server after changing environment variables.

Do not add an Auth0 client secret or Google client secret to Vite environment variables. Variables prefixed with VITE_ are exposed to the browser.

One thing to watch if you're on Vite: the official Auth0 docs use getElementById('app'), but Vite's default HTML template uses id="root". Make sure the selector matches your actual index.html.

Build the Authentication Component

When a user clicks "Sign in with Google," loginWithRedirect sends them to Google's authentication page. Google authenticates them and redirects to Auth0’s callback endpoint, and Auth0 completes the flow back to your application with an authorization code. Auth0 exchanges that code for tokens, and your app picks up on the other side with isAuthenticated: true and a populated user object.

import React from 'react';
import { useAuth0 } from '@auth0/auth0-react';

function App() {
  const { isLoading, isAuthenticated, error, user, loginWithRedirect, logout } =
    useAuth0();

  if (isLoading) {
    return <div>Loading...</div>;
  }
  if (error) {
    return <div>Oops... {error.message}</div>;
  }

  if (isAuthenticated) {
    return (
      <div>
        Hello {user.name}{' '}
        <button
          onClick={() =>
            logout({ logoutParams: { returnTo: window.location.origin } })
          }
        >
          Log out
        </button>
      </div>
    );
  }  
  return (
    <button
      onClick={() =>
        loginWithRedirect({
          authorizationParams: {
            connection: 'google-oauth2',
          },
        })
      }
    >
      Sign in with Google
    </button>
  );
  
}

export default App;

isLoading is true while Auth0 is restoring session state on page load, before it knows whether the user is already logged in. You want to handle it so you're not briefly rendering the login button to an authenticated user on every refresh.

The connection: 'google-oauth2' parameter tells Auth0 to redirect the users directly to the Google login screen instead of using Auth0’s own Universal Login’s provider-selection screen first. That's the connection identifier Auth0 uses for the Google social provider. Without it, users land on the Auth0 hosted login page first, where they'd choose their provider manually.

The user object commonly includes normalized claims such as name, email, and picture, subject to the scopes requested and the data available from Google. Always treat them as optional claims in your UI.

Auth0 enables a Google connection for every new tenant using shared developer keys, which is why this works without any Google Cloud setup. Those shared keys are fine for development, but not for a production app.

Going to Production: Your Own Google Credentials

Before moving to production you must change the shared dev keys for your own.

Auth0 development keys are useful for trying the connection quickly, but use Google OAuth credentials owned by your organization before production. This gives you control over the Google OAuth consent-screen branding, publishing status, redirect configuration, and operational lifecycle of the integration. Shared keys are thus not meant for production, and using them may raise unexpected errors. You can learn more about it here

Next we’ll set up all the required steps to get your Google social connection ready for production.

Create OAuth Credentials in Google Cloud Console

In Google Cloud Console, go to Google Auth Platform > Clients > New Client. Set the application type to Web application and give it a name.

Fill in the following fields:

Authorized JavaScript origins:

https://YOUR-AUTH0-DOMAIN

Authorized redirect URIs:

https://YOUR-AUTH0-DOMAIN/login/callback

The origin is your Auth0 tenant domain, not your app's domain. The redirect URI is Auth0's callback endpoint where Google sends the user after authentication. Google validates both against its own allowlist, the same way Auth0 validates redirect URIs on its side.

If your Google Cloud project is brand new, Google may prompt you to configure an OAuth consent screen first. You'll need to add your app name, support email, and domain. Once that's done, come back and finish creating the client.

Click Create and copy the Client ID and Client Secret before closing the dialog. Google only shows the secret once.

Add the Credentials to Auth0

In Auth0, go to Authentication > Social > Google. Replace the dev keys with your Client ID and Client Secret and save.

Under the Applications tab in the same connection, confirm your app is still listed as enabled. If you have multiple applications in your tenant, social connections aren't enabled for all of them by default.

From the user's perspective the login flow looks identical. The only visible difference is that Google's consent screen now shows your app's name, which is what it should have been showing all along.

What to Build From Here

Google login is working, but right now any component can render regardless of whether the user is signed in. The Auth0 React SDK has a withAuthenticationRequired higher-order component that handles route protection. Wrap any component with it and Auth0 will redirect unauthenticated users to the login page automatically before letting them through.

The other natural next step is calling a protected API. useAuth0 exposes a getAccessTokenSilently method that returns a short-lived access token you can attach to API requests. You configure which API the token is scoped to by passing an audience parameter to Auth0Provider, that audience maps to an API you register separately in your Auth0 dashboard. Once that's set up, you can protect your back-end routes by validating the token on the server side.

If you want to offer more than Google, the pattern is the same for every social provider Auth0 supports. GitHub, Facebook, Microsoft, Apple, you add the connection in Auth0, register OAuth credentials with that provider, and pass the appropriate connection identifier to loginWithRedirect. You can offer multiple providers on the same login flow, or use the connection parameter to route users to a specific one depending on context.

Frequently Asked Questions

Yes. The setup is the same for every social provider Auth0 supports. Go to Authentication > Social in your Auth0 dashboard, enable the provider, register OAuth credentials on that provider's platform, and add those credentials to the Auth0 connection settings. In your React code, pass the appropriate connection identifier to loginWithRedirect. For GitHub, that's github; for Microsoft, it's windowslive.
It's on the user object from useAuth0. Google sends back user.picture as a URL to the user's Google profile photo. You can render it directly in an <img> tag. The user object also includes user.email, user.name, user.given_name, and user.family_name from Google's profile data.
Yes, with an Auth0 Action. In Actions > Flows > Login, add a custom Action that checks the event.user.email domain and calls api.access.deny() if it doesn't match. That runs server-side during the login flow before Auth0 issues tokens. You can also pass hd (hosted domain) as an authorization parameter to hint to Google which domain you expect, but Auth0's Action is the enforcement layer you actually want.
The @auth0/auth0-react SDK is for client-side SPAs. For Next.js, use @auth0/nextjs-auth0 instead. It's a different package with server-side session handling built for Next.js's request/response model. The Auth0 Application setup and Google connection steps are the same either way.
The redirect URI in your request has to match the value in your Auth0 Application's Allowed Callback URLs exactly, including protocol, port, and trailing slashes. The most common issue when moving to production is adding the production URL to the environment variables but forgetting to add it to the callback list in the Auth0 dashboard. Check both, and make sure there are no trailing slashes in one but not the other.

About the author

Carla Urrea Stabile

Carla Urrea Stabile

Staff Developer Advocate

I've been working as a software engineer since 2014, particularly as a backend engineer and doing system design. I consider myself a language-agnostic developer but if I had to choose, I like to work with Ruby and Python.

After realizing how fun it was to create content and share experiences with the developer community I made the switch to Developer Advocacy. I like to learn and work with new technologies.

When I'm not coding or creating content you could probably find me going on a bike ride, hiking, or just hanging out with my dog, Dasha.

View profile