Clerk logo

Clerk Docs

Ctrl + K
Go to clerk.dev

Get started with React

Learn to install and initialize Clerk in a new Create React App.

Overview

Clerk is the easiest way to add authentication and user management to your React application. This guide will walk you through the necessary steps to install and use Clerk in a new create-react-app application.

After following this guide, you should have a working React app complete with:

  • Fully fledged sign in and sign up flows.
  • Google Social Login.
  • Secure email/password authentication.
  • A prebuilt user profile page.

Looking for a quickstart? We created a demo app to show you how to add Clerk to your project.

Before you start

You need to create a Clerk Application in your Clerk Dashboard. For more information, check out our Set up your application guide.

Creating a new React app

Start by creating a new React application - this is usually done using the create-react-app CLI:

1
npx create-react-app
1
yarn create react-app

Installing Clerk

Once you have a React app ready, you need to install the Clerk React SDK. This will give you access to our prebuilt Clerk Components and React hooks.

1
# Navigate to your application's root directory
2
# This should be the actual name from
3
# the previous step
4
cd my-first-application
5
6
# Install the clerk-react package
7
npm install @clerk/clerk-react
1
# Navigate to your application's root directory
2
# This should be the actual name from
3
# the previous step
4
cd my-first-application
5
6
# Install the clerk-react package
7
yarn add @clerk/clerk-react

Set Environment Keys

Below is an example of your .env.local file. To get the respective keys go to the API Keys page in the Clerk dashboard.

.env.local
1

It is also possible to pass these keys into the Clerk components and functions manually.

Clerk is now successfully installed!

To run your app, start the development server and navigate to http://localhost:3000.

1
npm start
1
yarn start

For more details, consult the Clerk React installation page.

Adding <ClerkProvider />

Clerk requires your application to be wrapped in the <ClerkProvider/> context. In React, we add this in src/App.jsx.

Wrap your app with <ClerkProvider/> and pass the REACT_APP_CLERK_PUBLISHABLE_KEY env variable you just created to the publishableKey prop. Replace your src/App.jsx with:

import React from "react";
import "./App.css";
import { ClerkProvider } from "@clerk/clerk-react";
const clerkPubKey = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY;
function App() {
return (
// Wrap your entire app with ClerkProvider
// Don't forget to pass the publishableKey prop
<ClerkProvider publishableKey={clerkPubKey}>
<Hello />
</ClerkProvider>
);
}
function Hello() {
return <div>Hello from Clerk</div>;
}
export default App;

Navigate to http://localhost:3000 so we can start viewing the changes but note that you won't see any changes yet.

Requiring authentication

The easiest way to require authentication before showing a protected page is to use our Control Components:

The following example shows you how to compose our flexible Control Components to build auth flows that match your needs. Please note that you don't need to use any additional APIs, everything shown below is just Javascript.

Visit http://localhost:3000 to see your page - you'll immediately get redirected to the Clerk Hosted Sign In page:

import React from "react";
import "./App.css";
import {
ClerkProvider,
SignedIn,
SignedOut,
UserButton,
useUser,
RedirectToSignIn,
} from "@clerk/clerk-react";
// Get the Publishable Key from the environment
const clerk_pub_key = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY;
function App() {
return (
// Wrap your entire app with ClerkProvider
// Don't forget to pass the frontendApi prop
<ClerkProvider publishableKey={clerk_pub_key}>
<SignedIn>
<Hello />
</SignedIn>
<SignedOut>
<RedirectToSignIn />
</SignedOut>
</ClerkProvider>
);
}
function Hello() {
return <div>Hello from Clerk</div>;
}
export default App;

Hello, world!

That's all you need to start using Clerk. Now you can say hello to your user!

Let's edit the <Hello/> component. We're going to use the useUser hook and the UserButton component as shown in the example:

import React from "react";
import "./App.css";
import {
ClerkProvider,
SignedIn,
SignedOut,
UserButton,
useUser,
RedirectToSignIn,
} from "@clerk/clerk-react";
const clerk_pub_key = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY;
function App() {
return (
// Wrap your entire app with ClerkProvider
<ClerkProvider publishableKey={clerk_pub_key}>
<SignedIn>
<Hello />
</SignedIn>
<SignedOut>
<RedirectToSignIn />
</SignedOut>
</ClerkProvider>
);
}
function Hello() {
// Get the user's first name
const { user } = useUser();
return (
<div className="App-header">
{/* Mount the UserButton component */}
<UserButton />
{user ? <h1>Hello, {user.firstName}!</h1> : null}
</div>
);
}
export default App;

Visit https://localhost:3000 again to see your page. If you haven't signed in yet, you will be redirected to the sign in page. Sign in using your preferred method and the home page will become accessible.

By default, your app will use the Clerk Hosted Pages to display the sign-in and sign-up flows. Check the documentation of the <SignIn/> and <SignUp/> components to learn how you can mount them directly in your app.

Optionally, we can add a router. Here's how:

Adding a router

<ClerkProvider/> also accepts a navigate prop that enables Clerk to navigate inside your application without a full page reload, using the same routing logic your app does. Our display components use this prop when navigating between subpages, and when navigating to callback URLs.

You can pass the navigate prop a function that takes the destination URL as an argument and performs a "push" navigation. You should not implement the push yourself, but instead, wrap the push function provided by your router. Most React apps use the popular react-router-dom, which is also what we'll be using for this guide. Install it by running the following command:

1
npm i react-router-dom
1
yarn add react-router-dom

Wrap your <App/> component with the router by modifying the src/index.jsx file as shown below:

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<React.StrictMode>
{/* Wrap your App component with the Router */}
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById("root")
);
reportWebVitals();

The last step is to give ClerkProvider access to your router, by adding the navigate prop. In src/App.jsx import and use the useNavigate hook, as shown in the example:

import {
ClerkProvider,
SignedIn,
SignIn,
SignUp
} from "@clerk/clerk-react";
import {
BrowserRouter,
Route,
Routes,
useNavigate
} from "react-router-dom";
const clerk_pub_key = process.env.REACT_APP_CLERK_PUBLISHABLE_KEY;
function PublicPage() {
return <h1>Public page</h1>;
}
function ProtectedPage() {
return <h1>Protected page</h1>;
}
function ClerkProviderWithRoutes() {
const navigate = useNavigate();
return (
<ClerkProvider
publishableKey={clerk_pub_key}
navigate={(to) => navigate(to)}
>
<Routes>
<Route path="/" element={<PublicPage />} />
<Route
path="/sign-in"
element={<SignIn routing="path" path="/sign-in" />}
/>
<Route
path="/sign-up"
element={<SignUp routing="path" path="/sign-up" />}
/>
<Route
path="/protected"
element={
<SignedIn>
<ProtectedPage />
</SignedIn>
}
/>
</Routes>
</ClerkProvider>
);
}
function App() {
return (
<BrowserRouter>
<ClerkProviderWithRoutes />
</BrowserRouter>
);
}
export default App;

Next steps

You now have a working React + Clerk app. Going forward, you can:

Was this helpful?

Clerk © 2023