User authentication is an integral part of any application—whether a web app, mobile app, or an entire organization's infrastructure. It ensures that only authorized users can access specific resources, data, or services. It helps to prevent data breaches, unauthorized access, and other security threats. Authentication in React, while straightforward for experienced developers, can be complicated for beginners. This also depends on the features the developers want to include in their authentication, like passwordless login (Google, Facebook, Apple, etc.), multi-factor authentication, and user roles. The more features included, the more detailed it becomes. That is where Clerk comes in, providing a simple solution without the hassle of building from scratch. What is Clerk? Clerk is a user management platform that simplifies the authentication process and offers everything needed for user authentication and management, including features like user profiles, sessions, passwordless login, Multi-factor authentication, Email and SMS OTP and many more. Clerk also supports a variety of frameworks (Frontend and Backend) and integrations like NextJs, React, Node/Express, Ruby on Rails, Firebase, Supabase, Hasura, Google Analytics and others. In this tutorial, we will build a simple authentication app using React. And we'll style it using Tailwindcss. Beginner developers should learn to build user authentication from scratch to understand the process and how to implement it effectively. Prerequisites Before starting this tutorial, you should have a good understanding of the fundamentals of JavaScript and React. Additionally, you must have the following software installed on your computer: Node.js: Install Node.js to manage the asset pipeline and run JavaScript code. npm or yarn (package manager) A code editor, like VS Code A browser like Google Chrome Step 1: Create a New React App With Vite To create a new React app, navigate to your preferred directory, and run npm create vite@latest clerkapp. Select your preferred framework and variant. In this case, I'll be using React and JavaScript. This will create a new React application called clerkapp. Open this directory in your preferred text editor. To install the dependencies, run npm install. Then launch the app: npm run dev. Open http://localhost:5173/ in your browser to access the Vite welcome page. Step 2: Install and Configure Tailwindcss To install Tailwindcss, run: npm install -D tailwindcss postcss autoprefixer Generate the config files: npx tailwindcss init -p Update the content field in the tailwind.config.js /** @type {import('tailwindcss').Config} */ export default { content: [ "./index.html", "./src/**/*.{js,ts,jsx,tsx}", ], theme: { extend: {}, }, plugins: [], } In src/index.css, remove the boilerplate designs and add: @tailwind base; @tailwind components; @tailwind utilities; Navigate to App.jsx , and remove the boilerplate code and replace it with: import React from 'react'; const App = () => { return ( <div className="min-h-screen bg-purple-300 flex items-center justify-center"> <h1 className="text-indigo-400 font-bold">Hello, TailwindCSS!</h1> </div> ); }; export default App; Restart the server, and see the new changes. Note: Sometimes, Tailwindcss may not take effect immediately. In such a case, you can either uninstall and then reinstall Tailwindcss or regenerate the config files: npx tailwindcss init -p Step 3: Install and Configure Clerk for Authentication Sign up to create a Clerk account, or sign in if you already have one. If the clerk's website does not open, use a secure VPN to access the website. Once logged in, you'll see a page that asks you to build your sign-in. This page is basically for you to configure your application name as well as sign-in options which can all be later changed in your dashboard if need be. For this article, we'll settle with the basics. I'll call the application ClerkApp and use Email, Username, and Google as my sign-in options. Feel free to customize it to your preferred sign-in options. Once you create the application, you'll be redirected to your dashboard where you can proceed to choose your preferred framework, in this case, React. Navigate to the terminal, and install Clerk for React. npm install @clerk/clerk-react. Create a .env.local file in your root folder to set up your environment variables, and add your API key. It should look like: VITE_CLERK_PUBLISHABLE_KEY=pk_test_w29vZmJjYXNpbmctY29ucmF0ZS0xMy5jbGVyay5hY2NvdW50cy5kZXYkRg This is a fake publishable key. Step 4: Integrate Clerk Into the App Navigate to the main.jsx file to import your Clerk publishable key, and wrap your app with Clerk's ClerkProvider component to enable authentication features throughout the app. import React from 'react'; import ReactDOM from 'react-dom/client' import App from './App'; import './index.css'; import { ClerkProvider } from '@clerk/clerk-react'; const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY; if (!PUBLISHABLE_KEY) { throw new Error('Clerk publishable key is missing.'); } ReactDOM.createRoot(document.getElementById('root')).render( <ClerkProvider publishableKey={PUBLISHABLE_KEY}> <App /> </ClerkProvider> ); Step 5: Create Navigation Components. In this step, we'll create the app navigation components: the Header, the Layout, the Homepage and the Dashboard. Install react-router-dom to enable page navigation. npm install react-router-dom In the src folder, create a new components folder and cd into it. This is where we'll store all of our authentication components and layouts. In the components folder, create a new file called Header.jsx .Add the following code: import React from 'react'; import { Link } from 'react-router-dom'; import { useUser, useClerk } from '@clerk/clerk-react'; const Header = () => { const { user } = useUser(); const { signOut } = useClerk(); return ( <nav className="flex items-center justify-between px-6 py-4 mb-5 bg-black"> <div className="flex items-center"> <Link to="/"> <div className="text-lg font-bold text-purple-300 uppercase"> ClerkApp </div> </Link> </div> <div className="flex items-center text-purple-200"> {!user && ( <> <Link to="/sign-in" className="text-purple-300 hover:text-purple-400 mr-4" > Sign In </Link> <Link to="/sign-up" className="text-purple-300 hover:text-purple-400 mr-4" > Sign Up </Link> </> )} {user && ( <> <Link to="/profile" className="text-purple-300 hover:text-purple-400 mr-4" > Profile </Link> <button onClick={() => signOut()} className="text-purple-300 hover:text-purple-400" > Sign Out </button> </> )} </div> </nav> ); }; export default Header; Create a new file, and call it Dashboard.jsx. This is the page users will see once signed in. It'll include a small welcome message with the username. We'll use the useUser hook from the Clerk library to display the username. import React from 'react'; import { useUser } from '@clerk/clerk-react'; const Dashboard = () => { const { user } = useUser(); return ( <div className="min-h-screen bg-purple-50 flex flex-col items-center justify-center"> <div className="bg-white shadow-lg rounded-xl p-10 w-full max-w-lg"> <h1 className="text-4xl font-extrabold text-purple-600 mb-6">Dashboard</h1> <p className="text-lg text-gray-700 mb-6 font-bold text-purple-800 capitalize"> Hello {user ? user.username : user.fisrtName}! </p> <p> Welcome to Clerk App, where you can manage your User Authentication with ease.</p> </div> </div> ); }; export default Dashboard; Create a new file, and call it Layout.jsx. This is a wrapper component for the app to ensure the Header component is consistently displayed across various parts of the app. You are free to customize it to your needs. import React from 'react'; import Header from './Header'; const Layout = ({ children }) => ( <div className="layout-container"> <Header /> <main>{children}</main> </div> ); export default Layout; Create a new file called HomePage.jsx, this will be the app's landing page. This page can be accessed by both authenticated and unauthenticated users. import React from 'react'; const HomePage = () => { return ( <div className="flex flex-col items-center justify-center min-h-screen bg-gray-100 p-4"> <h1 className="text-4xl font-bold text-purple-600 mb-4">Welcome to Clerk App</h1> <p className="text-lg text-gray-700 mb-2">This is a public homepage that anyone can view.</p> <p className="text-md text-gray-600">Please sign in to access more features.</p> </div> ); }; export default HomePage; Step 6: Create Authentication Components. In this step, we'll create all the components involved in user authentication. The Sign-in, the Sign-up, and Profile components. In the components folder, create a new SignIn.jsx file for the sign-in component. import React from 'react'; import { SignIn } from '@clerk/clerk-react'; const SignInPage = () => ( <div className="flex items-center justify-center min-h-screen"> <div className="text-center"> <SignIn path="/sign-in" routing="path" /> </div> </div> ); export default SignInPage; Create a new SignUp.jsx file for the sign-up component. import React from 'react'; import { SignUp } from '@clerk/clerk-react'; const SignUpPage = () => ( <div className="flex items-center justify-center min-h-screen"> <div className="text-center"> <SignUp path="/sign-up" routing="path" /> </div> </div> ); export default SignUpPage; Create a Profile.jsx file for the profile component. import React from 'react'; import { UserProfile } from '@clerk/clerk-react'; const Profile = () => { return ( <div className="flex items-center justify-center min-h-screen"> <UserProfile path="/profile" routing="path" /> </div> ); }; export default Profile; Step 7: Rendering All the Components in App.jsx Navigate to App.jsx, and import and render all the previously created components. import React from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Dashboard from './components/Dashboard'; import Profile from './components/Profile'; import SignInPage from './components/SignIn'; import SignUpPage from './components/SignUp'; import HomePage from './components/HomePage'; import Layout from './components/Layout'; import './index.css' const App = () => ( <Router> <Layout> <Routes> <Route path="/" element={<HomePage />} /> <Route path="/dashboard" element={<Dashboard />} /> <Route path="/profile" element={<Profile />} /> <Route path="/sign-in" element={<SignInPage />} /> <Route path="/sign-up" element={<SignUpPage />} /> </Routes> </Layout> </Router> ); export default App; Restart your server, and look at the changes. You should now have a page with a welcome message and be able to sign up, sign in, sign out, or view your profile. Step 8: Protecting Routes Now that the authentication is almost complete, we need to ensure that certain routes like Dashboard are restricted to unauthenticated users. To do this, we'll use Clerk's SignedIn, SignedOut and RedirectToSignIn components to handle this. Import the necessary Clerk components and add them to the top of your file. import { SignedIn, SignedOut, RedirectToSignIn } from '@clerk/clerk-react'; Set up public and protected routes: Define the Homepage as a public route since we want it accessible to all users. Wrap all the routes that require authentication (Dashboard and Profile) with the SignedIn component. Use the SignedOut component for public routes like the sign-in and sign-out routes which are accessible to unauthenticated users. Unauthorized access will be redirected to the sign-in page using the Clerk's RedirectToSignIn component. In the App.jsx file, your code should look like this: import React from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import { SignedIn, SignedOut, RedirectToSignIn } from '@clerk/clerk-react'; import Dashboard from './components/Dashboard'; import Profile from './components/Profile'; import SignInPage from './components/SignIn'; import SignUpPage from './components/SignUp'; import HomePage from './components/HomePage'; import Layout from './components/Layout'; import './index.css'; const App = () => { return ( <Router> <Layout> <Routes> {/* HomePage Route */} <Route path="/" element={<HomePage />} /> {/* Dashboard Route */} <Route path="/dashboard" element={ <SignedIn> <Dashboard /> </SignedIn> } /> {/* Profile Route */} <Route path="/profile" element={ <SignedIn> <Profile /> </SignedIn> } /> {/* Sign In Route */} <Route path="/sign-in" element={ <SignedOut> <SignInPage /> </SignedOut> } /> {/* Sign Up Route */} <Route path="/sign-up" element={ <SignedOut> <SignUpPage /> </SignedOut> } /> {/* Redirect unauthenticated to sign-in */} <Route path="*" element={ <SignedOut> <RedirectToSignIn /> </SignedOut> } /> </Routes> </Layout> </Router> ); }; export default App; The SignedIn component renders its children only if the user is signed In, the SignedOut component renders its children when the user is unauthenticated and the RedirectToSignIn component restricts unauthorized access. Step 9: Update the Header.jsx For easy navigation, we'll make some slight changes in the Header. We want authenticated users to be able to access their dashboard and homepage, so we will use conditional rendering to ensure that the Dashboard link is only visible when a user is signed in. import React from 'react'; import { Link } from 'react-router-dom'; import { useUser, useClerk } from '@clerk/clerk-react'; const Header = () => { const { user } = useUser(); const { signOut } = useClerk(); return ( <nav className="flex items-center justify-between px-6 py-4 mb-5 bg-black"> <div className="flex items-center"> <Link to="/"> <div className="text-lg font-bold text-purple-300 uppercase"> ClerkApp </div> </Link> </div> <div className="flex items-center text-purple-200"> {!user && ( <> <Link to="/sign-in" className="text-purple-300 hover:text-purple-400 mr-4 uppercase" > Sign In </Link> <Link to="/sign-up" className="text-purple-300 hover:text-purple-400 mr-4 uppercase" > Sign Up </Link> </> )} {user && ( <> <Link to="/dashboard" className="text-purple-300 hover:text-purple-400 mr-4" > Dashboard </Link> <Link to="/profile" className="text-purple-300 hover:text-purple-400 mr-4" > Profile </Link> <button onClick={() => signOut()} className="text-purple-300 hover:text-purple-400" > Sign Out </button> </> )} </div> </nav> ); }; export default Header; You have successfully integrated Clerk and set up user authentication for your application. Restart your development server to review the changes. The app should be fully authenticated. Conclusion In this tutorial, we used Clerk to add user authentication to our React app. We built an application where users can sign in, sign up, and access protected routes like the Dashboard and Profile. We also integrated TailwindCSS for styling. Additionally, we used conditional rendering in the Header component to improve navigation based on authentication status. To expand your understanding of Clerk and TailwindCSS, refer to their official documentation for more features and customization options. User authentication is an integral part of any application—whether a web app, mobile app, or an entire organization's infrastructure. It ensures that only authorized users can access specific resources, data, or services. It helps to prevent data breaches, unauthorized access, and other security threats. User authentication Authentication in React, while straightforward for experienced developers, can be complicated for beginners. This also depends on the features the developers want to include in their authentication, like passwordless login (Google, Facebook, Apple, etc.), multi-factor authentication, and user roles. The more features included, the more detailed it becomes. That is where Clerk comes in, providing a simple solution without the hassle of building from scratch. Clerk What is Clerk? What is Clerk? Clerk is a user management platform that simplifies the authentication process and offers everything needed for user authentication and management, including features like user profiles, sessions, passwordless login, Multi-factor authentication, Email and SMS OTP and many more. Clerk also supports a variety of frameworks (Frontend and Backend) and integrations like NextJs, React, Node/Express, Ruby on Rails, Firebase, Supabase, Hasura, Google Analytics and others. In this tutorial, we will build a simple authentication app using React. And we'll style it using Tailwindcss. Beginner developers should learn to build user authentication from scratch to understand the process and how to implement it effectively. Beginner developers should learn to build user authentication from scratch to understand the process and how to implement it effectively. Beginner developers should learn to build user authentication from scratch to understand the process and how to implement it effectively. Prerequisites Prerequisites Before starting this tutorial, you should have a good understanding of the fundamentals of JavaScript and React. Additionally, you must have the following software installed on your computer: Node.js: Install Node.js to manage the asset pipeline and run JavaScript code. npm or yarn (package manager) A code editor, like VS Code A browser like Google Chrome Node.js : Install Node.js to manage the asset pipeline and run JavaScript code. Node.js Node.js npm or yarn (package manager) npm yarn A code editor, like VS Code VS Code A browser like Google Chrome Step 1: Create a New React App With Vite Step 1: Create a New React App With Vite To create a new React app, navigate to your preferred directory, and run npm create vite@latest clerkapp. To create a new React app, navigate to your preferred directory, and run npm create vite@latest clerkapp . npm create vite@latest clerkapp Select your preferred framework and variant. In this case, I'll be using React and JavaScript. Select your preferred framework and variant. In this case, I'll be using React and JavaScript. This will create a new React application called clerkapp. Open this directory in your preferred text editor. This will create a new React application called clerkapp . Open this directory in your preferred text editor. clerkapp To install the dependencies, run npm install. To install the dependencies, run npm install . npm install Then launch the app: npm run dev. Then launch the app: npm run dev . npm run dev Open http://localhost:5173/ in your browser to access the Vite welcome page. Open http://localhost:5173/ in your browser to access the Vite welcome page. http://localhost:5173/ Step 2: Install and Configure Tailwindcss Step 2: Install and Configure Tailwindcss To install Tailwindcss, run: npm install -D tailwindcss postcss autoprefixer To install Tailwindcss, run: npm install -D tailwindcss postcss autoprefixer npm install -D tailwindcss postcss autoprefixer Generate the config files: npx tailwindcss init -p Generate the config files: npx tailwindcss init -p npx tailwindcss init -p Update the content field in the tailwind.config.js Update the content field in the tailwind.config.js tailwind.config.js /** @type {import('tailwindcss').Config} */ export default { content: [ "./index.html", "./src/**/*.{js,ts,jsx,tsx}", ], theme: { extend: {}, }, plugins: [], } /** @type {import('tailwindcss').Config} */ export default { content: [ "./index.html", "./src/**/*.{js,ts,jsx,tsx}", ], theme: { extend: {}, }, plugins: [], } In src/index.css, remove the boilerplate designs and add: In src/index.css , remove the boilerplate designs and add: src/index.css @tailwind base; @tailwind components; @tailwind utilities; @tailwind base; @tailwind components; @tailwind utilities; Navigate to App.jsx , and remove the boilerplate code and replace it with: Navigate to App.jsx , and remove the boilerplate code and replace it with: App.jsx import React from 'react'; const App = () => { return ( <div className="min-h-screen bg-purple-300 flex items-center justify-center"> <h1 className="text-indigo-400 font-bold">Hello, TailwindCSS!</h1> </div> ); }; export default App; import React from 'react'; const App = () => { return ( <div className="min-h-screen bg-purple-300 flex items-center justify-center"> <h1 className="text-indigo-400 font-bold">Hello, TailwindCSS!</h1> </div> ); }; export default App; Restart the server, and see the new changes. Restart the server, and see the new changes. Restart the server, and see the new changes. Note: Sometimes, Tailwindcss may not take effect immediately. In such a case, you can either uninstall and then reinstall Tailwindcss or regenerate the config files: npx tailwindcss init -p Note: Sometimes, Tailwindcss may not take effect immediately. In such a case, you can either uninstall and then reinstall Tailwindcss or regenerate the config files: npx tailwindcss init -p Note: Sometimes, Tailwindcss may not take effect immediately. In such a case, you can either uninstall and then reinstall Tailwindcss or regenerate the config files: npx tailwindcss init -p Step 3: Install and Configure Clerk for Authentication Step 3: Install and Configure Clerk for Authentication Sign up to create a Clerk account, or sign in if you already have one. If the clerk's website does not open, use a secure VPN to access the website. Sign up to create a Clerk account, or sign in if you already have one. If the clerk's website does not open, use a secure VPN to access the website. Clerk Once logged in, you'll see a page that asks you to build your sign-in. This page is basically for you to configure your application name as well as sign-in options which can all be later changed in your dashboard if need be. Once logged in, you'll see a page that asks you to build your sign-in. This page is basically for you to configure your application name as well as sign-in options which can all be later changed in your dashboard if need be. For this article, we'll settle with the basics. I'll call the application ClerkApp and use Email, Username, and Google as my sign-in options. Feel free to customize it to your preferred sign-in options. For this article, we'll settle with the basics. I'll call the application ClerkApp and use Email, Username, and Google as my sign-in options. Feel free to customize it to your preferred sign-in options. ClerkApp Once you create the application, you'll be redirected to your dashboard where you can proceed to choose your preferred framework, in this case, React. Once you create the application, you'll be redirected to your dashboard where you can proceed to choose your preferred framework, in this case, React. Navigate to the terminal, and install Clerk for React. npm install @clerk/clerk-react. Navigate to the terminal, and install Clerk for React. npm install @clerk/clerk-react. npm install @clerk/clerk-react. Create a .env.local file in your root folder to set up your environment variables, and add your API key. It should look like: Create a .env.local file in your root folder to set up your environment variables, and add your API key. It should look like: Create a .env.local file in your root folder to set up your environment variables, and add your API key. It should look like: .env.local VITE_CLERK_PUBLISHABLE_KEY=pk_test_w29vZmJjYXNpbmctY29ucmF0ZS0xMy5jbGVyay5hY2NvdW50cy5kZXYkRg This is a fake publishable key. VITE_CLERK_PUBLISHABLE_KEY=pk_test_w29vZmJjYXNpbmctY29ucmF0ZS0xMy5jbGVyay5hY2NvdW50cy5kZXYkRg This is a fake publishable key. Step 4: Integrate Clerk Into the App Step 4: Integrate Clerk Into the App Navigate to the main.jsx file to import your Clerk publishable key, and wrap your app with Clerk's ClerkProvider component to enable authentication features throughout the app. Navigate to the main.jsx file to import your Clerk publishable key, and wrap your app with Clerk's ClerkProvider component to enable authentication features throughout the app. main.jsx ClerkProvider import React from 'react'; import ReactDOM from 'react-dom/client' import App from './App'; import './index.css'; import { ClerkProvider } from '@clerk/clerk-react'; const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY; if (!PUBLISHABLE_KEY) { throw new Error('Clerk publishable key is missing.'); } ReactDOM.createRoot(document.getElementById('root')).render( <ClerkProvider publishableKey={PUBLISHABLE_KEY}> <App /> </ClerkProvider> ); import React from 'react'; import ReactDOM from 'react-dom/client' import App from './App'; import './index.css'; import { ClerkProvider } from '@clerk/clerk-react'; const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY; if (!PUBLISHABLE_KEY) { throw new Error('Clerk publishable key is missing.'); } ReactDOM.createRoot(document.getElementById('root')).render( <ClerkProvider publishableKey={PUBLISHABLE_KEY}> <App /> </ClerkProvider> ); Step 5: Create Navigation Components. Step 5: Create Navigation Components. In this step, we'll create the app navigation components: the Header, the Layout, the Homepage and the Dashboard. Install react-router-dom to enable page navigation. npm install react-router-dom Install react-router-dom to enable page navigation. npm install react-router-dom npm install react-router-dom In the src folder, create a new components folder and cd into it. This is where we'll store all of our authentication components and layouts. In the src folder, create a new components folder and cd into it. This is where we'll store all of our authentication components and layouts. src components cd In the components folder, create a new file called Header.jsx .Add the following code: In the components folder, create a new file called Header.jsx .Add the following code: Header.jsx import React from 'react'; import { Link } from 'react-router-dom'; import { useUser, useClerk } from '@clerk/clerk-react'; const Header = () => { const { user } = useUser(); const { signOut } = useClerk(); return ( <nav className="flex items-center justify-between px-6 py-4 mb-5 bg-black"> <div className="flex items-center"> <Link to="/"> <div className="text-lg font-bold text-purple-300 uppercase"> ClerkApp </div> </Link> </div> <div className="flex items-center text-purple-200"> {!user && ( <> <Link to="/sign-in" className="text-purple-300 hover:text-purple-400 mr-4" > Sign In </Link> <Link to="/sign-up" className="text-purple-300 hover:text-purple-400 mr-4" > Sign Up </Link> </> )} {user && ( <> <Link to="/profile" className="text-purple-300 hover:text-purple-400 mr-4" > Profile </Link> <button onClick={() => signOut()} className="text-purple-300 hover:text-purple-400" > Sign Out </button> </> )} </div> </nav> ); }; export default Header; import React from 'react'; import { Link } from 'react-router-dom'; import { useUser, useClerk } from '@clerk/clerk-react'; const Header = () => { const { user } = useUser(); const { signOut } = useClerk(); return ( <nav className="flex items-center justify-between px-6 py-4 mb-5 bg-black"> <div className="flex items-center"> <Link to="/"> <div className="text-lg font-bold text-purple-300 uppercase"> ClerkApp </div> </Link> </div> <div className="flex items-center text-purple-200"> {!user && ( <> <Link to="/sign-in" className="text-purple-300 hover:text-purple-400 mr-4" > Sign In </Link> <Link to="/sign-up" className="text-purple-300 hover:text-purple-400 mr-4" > Sign Up </Link> </> )} {user && ( <> <Link to="/profile" className="text-purple-300 hover:text-purple-400 mr-4" > Profile </Link> <button onClick={() => signOut()} className="text-purple-300 hover:text-purple-400" > Sign Out </button> </> )} </div> </nav> ); }; export default Header; Create a new file, and call it Dashboard.jsx. This is the page users will see once signed in. It'll include a small welcome message with the username. We'll use the useUser hook from the Clerk library to display the username. Create a new file, and call it Dashboard.jsx . This is the page users will see once signed in. It'll include a small welcome message with the username. We'll use the useUser hook from the Clerk library to display the username. Dashboard.jsx useUser import React from 'react'; import { useUser } from '@clerk/clerk-react'; const Dashboard = () => { const { user } = useUser(); return ( <div className="min-h-screen bg-purple-50 flex flex-col items-center justify-center"> <div className="bg-white shadow-lg rounded-xl p-10 w-full max-w-lg"> <h1 className="text-4xl font-extrabold text-purple-600 mb-6">Dashboard</h1> <p className="text-lg text-gray-700 mb-6 font-bold text-purple-800 capitalize"> Hello {user ? user.username : user.fisrtName}! </p> <p> Welcome to Clerk App, where you can manage your User Authentication with ease.</p> </div> </div> ); }; export default Dashboard; import React from 'react'; import { useUser } from '@clerk/clerk-react'; const Dashboard = () => { const { user } = useUser(); return ( <div className="min-h-screen bg-purple-50 flex flex-col items-center justify-center"> <div className="bg-white shadow-lg rounded-xl p-10 w-full max-w-lg"> <h1 className="text-4xl font-extrabold text-purple-600 mb-6">Dashboard</h1> <p className="text-lg text-gray-700 mb-6 font-bold text-purple-800 capitalize"> Hello {user ? user.username : user.fisrtName}! </p> <p> Welcome to Clerk App, where you can manage your User Authentication with ease.</p> </div> </div> ); }; export default Dashboard; Create a new file, and call it Layout.jsx. This is a wrapper component for the app to ensure the Header component is consistently displayed across various parts of the app. You are free to customize it to your needs. Create a new file, and call it Layout.jsx . This is a wrapper component for the app to ensure the Header component is consistently displayed across various parts of the app. You are free to customize it to your needs. Layout.jsx import React from 'react'; import Header from './Header'; const Layout = ({ children }) => ( <div className="layout-container"> <Header /> <main>{children}</main> </div> ); export default Layout; import React from 'react'; import Header from './Header'; const Layout = ({ children }) => ( <div className="layout-container"> <Header /> <main>{children}</main> </div> ); export default Layout; Create a new file called HomePage.jsx, this will be the app's landing page. This page can be accessed by both authenticated and unauthenticated users. Create a new file called HomePage.jsx , this will be the app's landing page. This page can be accessed by both authenticated and unauthenticated users. HomePage.jsx import React from 'react'; const HomePage = () => { return ( <div className="flex flex-col items-center justify-center min-h-screen bg-gray-100 p-4"> <h1 className="text-4xl font-bold text-purple-600 mb-4">Welcome to Clerk App</h1> <p className="text-lg text-gray-700 mb-2">This is a public homepage that anyone can view.</p> <p className="text-md text-gray-600">Please sign in to access more features.</p> </div> ); }; export default HomePage; import React from 'react'; const HomePage = () => { return ( <div className="flex flex-col items-center justify-center min-h-screen bg-gray-100 p-4"> <h1 className="text-4xl font-bold text-purple-600 mb-4">Welcome to Clerk App</h1> <p className="text-lg text-gray-700 mb-2">This is a public homepage that anyone can view.</p> <p className="text-md text-gray-600">Please sign in to access more features.</p> </div> ); }; export default HomePage; Step 6: Create Authentication Components. Step 6: Create Authentication Components. In this step, we'll create all the components involved in user authentication. The Sign-in, the Sign-up, and Profile components. In the components folder, create a new SignIn.jsx file for the sign-in component. In the components folder, create a new SignIn.jsx file for the sign-in component. SignIn.jsx import React from 'react'; import { SignIn } from '@clerk/clerk-react'; const SignInPage = () => ( <div className="flex items-center justify-center min-h-screen"> <div className="text-center"> <SignIn path="/sign-in" routing="path" /> </div> </div> ); export default SignInPage; import React from 'react'; import { SignIn } from '@clerk/clerk-react'; const SignInPage = () => ( <div className="flex items-center justify-center min-h-screen"> <div className="text-center"> <SignIn path="/sign-in" routing="path" /> </div> </div> ); export default SignInPage; Create a new SignUp.jsx file for the sign-up component. Create a new SignUp.jsx file for the sign-up component. SignUp.jsx import React from 'react'; import { SignUp } from '@clerk/clerk-react'; const SignUpPage = () => ( <div className="flex items-center justify-center min-h-screen"> <div className="text-center"> <SignUp path="/sign-up" routing="path" /> </div> </div> ); export default SignUpPage; import React from 'react'; import { SignUp } from '@clerk/clerk-react'; const SignUpPage = () => ( <div className="flex items-center justify-center min-h-screen"> <div className="text-center"> <SignUp path="/sign-up" routing="path" /> </div> </div> ); export default SignUpPage; Create a Profile.jsx file for the profile component. Create a Profile.jsx file for the profile component. Profile.jsx import React from 'react'; import { UserProfile } from '@clerk/clerk-react'; const Profile = () => { return ( <div className="flex items-center justify-center min-h-screen"> <UserProfile path="/profile" routing="path" /> </div> ); }; export default Profile; import React from 'react'; import { UserProfile } from '@clerk/clerk-react'; const Profile = () => { return ( <div className="flex items-center justify-center min-h-screen"> <UserProfile path="/profile" routing="path" /> </div> ); }; export default Profile; Step 7: Rendering All the Components in App.jsx Step 7: Rendering All the Components in App.jsx Navigate to App.jsx, and import and render all the previously created components. Navigate to App.jsx , and import and render all the previously created components. App.jsx import React from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Dashboard from './components/Dashboard'; import Profile from './components/Profile'; import SignInPage from './components/SignIn'; import SignUpPage from './components/SignUp'; import HomePage from './components/HomePage'; import Layout from './components/Layout'; import './index.css' const App = () => ( <Router> <Layout> <Routes> <Route path="/" element={<HomePage />} /> <Route path="/dashboard" element={<Dashboard />} /> <Route path="/profile" element={<Profile />} /> <Route path="/sign-in" element={<SignInPage />} /> <Route path="/sign-up" element={<SignUpPage />} /> </Routes> </Layout> </Router> ); export default App; import React from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Dashboard from './components/Dashboard'; import Profile from './components/Profile'; import SignInPage from './components/SignIn'; import SignUpPage from './components/SignUp'; import HomePage from './components/HomePage'; import Layout from './components/Layout'; import './index.css' const App = () => ( <Router> <Layout> <Routes> <Route path="/" element={<HomePage />} /> <Route path="/dashboard" element={<Dashboard />} /> <Route path="/profile" element={<Profile />} /> <Route path="/sign-in" element={<SignInPage />} /> <Route path="/sign-up" element={<SignUpPage />} /> </Routes> </Layout> </Router> ); export default App; Restart your server, and look at the changes. You should now have a page with a welcome message and be able to sign up, sign in, sign out, or view your profile. Restart your server, and look at the changes. You should now have a page with a welcome message and be able to sign up, sign in, sign out, or view your profile. Restart your server, and look at the changes. You should now have a page with a welcome message and be able to sign up, sign in, sign out, or view your profile. Step 8: Protecting Routes Step 8: Protecting Routes Now that the authentication is almost complete, we need to ensure that certain routes like Dashboard are restricted to unauthenticated users. To do this, we'll use Clerk's SignedIn , SignedOut and RedirectToSignIn components to handle this. Dashboard SignedIn SignedOut RedirectToSignIn Import the necessary Clerk components and add them to the top of your file. Import the necessary Clerk components and add them to the top of your file. import { SignedIn, SignedOut, RedirectToSignIn } from '@clerk/clerk-react'; import { SignedIn, SignedOut, RedirectToSignIn } from '@clerk/clerk-react'; Set up public and protected routes: Define the Homepage as a public route since we want it accessible to all users. Set up public and protected routes: Define the Homepage as a public route since we want it accessible to all users. Homepage Wrap all the routes that require authentication (Dashboard and Profile) with the SignedIn component. Wrap all the routes that require authentication ( Dashboard and Profile ) with the SignedIn component. Dashboard and Profile SignedIn Use the SignedOut component for public routes like the sign-in and sign-out routes which are accessible to unauthenticated users. Use the SignedOut component for public routes like the sign-in and sign-out routes which are accessible to unauthenticated users. SignedOut sign-in sign-out Unauthorized access will be redirected to the sign-in page using the Clerk's RedirectToSignIn component. Unauthorized access will be redirected to the sign-in page using the Clerk's RedirectToSignIn component. RedirectToSignIn In the App.jsx file, your code should look like this: In the App.jsx file, your code should look like this: App.jsx import React from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import { SignedIn, SignedOut, RedirectToSignIn } from '@clerk/clerk-react'; import Dashboard from './components/Dashboard'; import Profile from './components/Profile'; import SignInPage from './components/SignIn'; import SignUpPage from './components/SignUp'; import HomePage from './components/HomePage'; import Layout from './components/Layout'; import './index.css'; const App = () => { return ( <Router> <Layout> <Routes> {/* HomePage Route */} <Route path="/" element={<HomePage />} /> {/* Dashboard Route */} <Route path="/dashboard" element={ <SignedIn> <Dashboard /> </SignedIn> } /> {/* Profile Route */} <Route path="/profile" element={ <SignedIn> <Profile /> </SignedIn> } /> {/* Sign In Route */} <Route path="/sign-in" element={ <SignedOut> <SignInPage /> </SignedOut> } /> {/* Sign Up Route */} <Route path="/sign-up" element={ <SignedOut> <SignUpPage /> </SignedOut> } /> {/* Redirect unauthenticated to sign-in */} <Route path="*" element={ <SignedOut> <RedirectToSignIn /> </SignedOut> } /> </Routes> </Layout> </Router> ); }; export default App; import React from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import { SignedIn, SignedOut, RedirectToSignIn } from '@clerk/clerk-react'; import Dashboard from './components/Dashboard'; import Profile from './components/Profile'; import SignInPage from './components/SignIn'; import SignUpPage from './components/SignUp'; import HomePage from './components/HomePage'; import Layout from './components/Layout'; import './index.css'; const App = () => { return ( <Router> <Layout> <Routes> {/* HomePage Route */} <Route path="/" element={<HomePage />} /> {/* Dashboard Route */} <Route path="/dashboard" element={ <SignedIn> <Dashboard /> </SignedIn> } /> {/* Profile Route */} <Route path="/profile" element={ <SignedIn> <Profile /> </SignedIn> } /> {/* Sign In Route */} <Route path="/sign-in" element={ <SignedOut> <SignInPage /> </SignedOut> } /> {/* Sign Up Route */} <Route path="/sign-up" element={ <SignedOut> <SignUpPage /> </SignedOut> } /> {/* Redirect unauthenticated to sign-in */} <Route path="*" element={ <SignedOut> <RedirectToSignIn /> </SignedOut> } /> </Routes> </Layout> </Router> ); }; export default App; The SignedIn component renders its children only if the user is signed In, the SignedOut component renders its children when the user is unauthenticated and the RedirectToSignIn component restricts unauthorized access. The SignedIn component renders its children only if the user is signed In, the SignedOut component renders its children when the user is unauthenticated and the RedirectToSignIn component restricts unauthorized access. The SignedIn component renders its children only if the user is signed In, the SignedOut component renders its children when the user is unauthenticated and the RedirectToSignIn component restricts unauthorized access. Step 9: Update the Header.jsx Step 9: Update the Header.jsx For easy navigation, we'll make some slight changes in the Header . Header We want authenticated users to be able to access their dashboard and homepage, so we will use conditional rendering to ensure that the Dashboard link is only visible when a user is signed in. import React from 'react'; import { Link } from 'react-router-dom'; import { useUser, useClerk } from '@clerk/clerk-react'; const Header = () => { const { user } = useUser(); const { signOut } = useClerk(); return ( <nav className="flex items-center justify-between px-6 py-4 mb-5 bg-black"> <div className="flex items-center"> <Link to="/"> <div className="text-lg font-bold text-purple-300 uppercase"> ClerkApp </div> </Link> </div> <div className="flex items-center text-purple-200"> {!user && ( <> <Link to="/sign-in" className="text-purple-300 hover:text-purple-400 mr-4 uppercase" > Sign In </Link> <Link to="/sign-up" className="text-purple-300 hover:text-purple-400 mr-4 uppercase" > Sign Up </Link> </> )} {user && ( <> <Link to="/dashboard" className="text-purple-300 hover:text-purple-400 mr-4" > Dashboard </Link> <Link to="/profile" className="text-purple-300 hover:text-purple-400 mr-4" > Profile </Link> <button onClick={() => signOut()} className="text-purple-300 hover:text-purple-400" > Sign Out </button> </> )} </div> </nav> ); }; export default Header; import React from 'react'; import { Link } from 'react-router-dom'; import { useUser, useClerk } from '@clerk/clerk-react'; const Header = () => { const { user } = useUser(); const { signOut } = useClerk(); return ( <nav className="flex items-center justify-between px-6 py-4 mb-5 bg-black"> <div className="flex items-center"> <Link to="/"> <div className="text-lg font-bold text-purple-300 uppercase"> ClerkApp </div> </Link> </div> <div className="flex items-center text-purple-200"> {!user && ( <> <Link to="/sign-in" className="text-purple-300 hover:text-purple-400 mr-4 uppercase" > Sign In </Link> <Link to="/sign-up" className="text-purple-300 hover:text-purple-400 mr-4 uppercase" > Sign Up </Link> </> )} {user && ( <> <Link to="/dashboard" className="text-purple-300 hover:text-purple-400 mr-4" > Dashboard </Link> <Link to="/profile" className="text-purple-300 hover:text-purple-400 mr-4" > Profile </Link> <button onClick={() => signOut()} className="text-purple-300 hover:text-purple-400" > Sign Out </button> </> )} </div> </nav> ); }; export default Header; You have successfully integrated Clerk and set up user authentication for your application. Restart your development server to review the changes. The app should be fully authenticated. You have successfully integrated Clerk and set up user authentication for your application. Restart your development server to review the changes. The app should be fully authenticated. You have successfully integrated Clerk and set up user authentication for your application. Restart your development server to review the changes. The app should be fully authenticated. Conclusion Conclusion In this tutorial, we used Clerk to add user authentication to our React app. We built an application where users can sign in, sign up, and access protected routes like the Dashboard and Profile. We also integrated TailwindCSS for styling. Additionally, we used conditional rendering in the Header component to improve navigation based on authentication status. Clerk TailwindCSS To expand your understanding of Clerk and TailwindCSS, refer to their official documentation for more features and customization options.