---
title: "Adding Google Login to a React App with Auth0
"
description: "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."
authors:
  - name: "Carla Urrea Stabile"
    url: "https://auth0.com/blog/authors/carla-stabile/"
date: "Sep 11, 2026"
category: "Developers,Tutorial"
tags: ["google-login", "react", "social-connection", "authentication"]
url: "https://auth0.com/blog/adding-google-login-to-react-app-with-auth0/"
---

# Adding Google Login to a React App with Auth0


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.

<AmpContent>
<amp-youtube
    data-videoid="qY3XsfQSD3c"
    layout="responsive"
    width="480" height="270">
</amp-youtube>
</AmpContent>
<NonAmpContent>
<div class='embed-container' style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%;margin-bottom:40px;"><iframe style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" src='https://www.youtube.com/embed/qY3XsfQSD3c' frameborder='0' allowfullscreen></iframe></div>
</NonAmpContent>


## 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


```bash
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](https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce). 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:


```js
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:


```bash
# .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.


```js
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](https://auth0.com/docs/authenticate/identity-providers/social-identity-providers/devkeys)

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](https://console.cloud.google.com), 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.


<FAQs>
  <FAQ>
    <FAQQuestion>Can I add other social providers like GitHub alongside Google?</FAQQuestion>
    <FAQAnswer>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`.</FAQAnswer>
  </FAQ>
  <FAQ>
    <FAQQuestion>How do I get the user's profile picture?</FAQQuestion>
    <FAQAnswer>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.</FAQAnswer>
  </FAQ>
  <FAQ>
    <FAQQuestion>Can I restrict Google login to users from a specific email domain?</FAQQuestion>
    <FAQAnswer>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.</FAQAnswer>
  </FAQ>
<FAQ>
    <FAQQuestion>Does this work with Next.js?</FAQQuestion>
    <FAQAnswer>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.</FAQAnswer>
  </FAQ>
<FAQ>
    <FAQQuestion>Why is Auth0 rejecting my redirect URI after login?</FAQQuestion>
    <FAQAnswer>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.</FAQAnswer>
  </FAQ>
</FAQs>
