Add React Router to your Clerk-powered Chrome Extension
You will learn the following:
- Install
react-router-dom
- Create components for your routes
- Create layouts
- Wire layouts and routes up with
createMemoryRouter
Before you start
Example repository
This tutorial demonstrates how to integrate React Router into your Chrome Extension application.
Install react-router-dom
React Router is a lightweight, fully-featured routing library. To install it in your project, run the following command:
pnpm add react-router-dom
Create routes
- In the
src/
directory, create apopup/
directory. - In the
popup/
directory, create aroutes/
directory. - In the
routes/
directory, create thehome.tsx
,sign-in.tsx
,sign-up.tsx
, andsettings.tsx
files. - Use the following tabs to view the code necessary for each file.
export const Home = () => {
return (
<>
<h1>Clerk + Chrome Extension + React Router</h1>
</>
)
}
import { SignIn } from '@clerk/chrome-extension'
export const SignInPage = () => {
return (
<>
<p>Sign In</p>
<SignIn routing="virtual" />
</>
)
}
import { SignUp } from '@clerk/chrome-extension'
export const SignUpPage = () => {
return (
<>
<p>Sign Up</p>
<SignUp routing="virtual" />
</>
)
}
import { UserProfile } from '@clerk/chrome-extension'
export const Settings = () => {
return (
<>
<h1>Settings</h1>
<UserProfile routing="virtual" />
</>
)
}
Create layouts
- Delete your
src/popup.tsx
file. - In your
src/popup/
directory, create alayouts/
directory. - In the
layouts/
directory, create aroot-layout.tsx
file. - In the
root-layout.tsx
file, paste the following code to create a layout for your app.- The layout contains an
<Outlet />
component fromreact-router-dom
. This behaves similar to{children}
in Next.js or more generic React components. - The footer includes Clerk's
<UserButton />
component and a link to the/settings
page, which renders Clerk's<UserProfile />
component. Clerk's<SignedIn>
and<SignedOut>
control components determine what's displayed based on the user's authentication state.
- The layout contains an
import { Link, Outlet, useNavigate } from 'react-router-dom'
import { ClerkProvider, SignedIn, SignedOut, UserButton } from '@clerk/chrome-extension'
const PUBLISHABLE_KEY = process.env.PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY
if (!PUBLISHABLE_KEY) {
throw new Error('Please add the PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY to the .env.development file')
}
export const RootLayout = () => {
const navigate = useNavigate()
return (
<ClerkProvider
routerPush={(to) => navigate(to)}
routerReplace={(to) => navigate(to, { replace: true })}
publishableKey={PUBLISHABLE_KEY}
afterSignOutUrl="/"
>
<div className="plasmo-w-[785px] plasmo-h-[600px]">
<main>
<Outlet />
</main>
<footer>
<SignedIn>
<Link to="/settings">Settings</Link>
<UserButton />
</SignedIn>
<SignedOut>
<Link to="/">Home</Link>
<Link to="/sign-in">Sign In</Link>
<Link to="/sign-up">Sign Up</Link>
</SignedOut>
</footer>
</div>
</ClerkProvider>
)
}
Configure layouts and routes with createMemoryRouter
React Router's createMemoryRouter
is a router that uses memory to store the state of the router instead of the browser's history. This is useful for creating a router in a non-browser environment like a Chrome Extension.
- In the
src/popup/
directory, create anindex.tsx
file. - In the
index.tsx
file, paste the following code to configure your routes withcreateMemoryRouter
.
import React from 'react'
import '../style.css'
import { createMemoryRouter, RouterProvider } from 'react-router-dom'
import { RootLayout } from './layouts/root-layout'
import { Home } from './routes/home'
import { Settings } from './routes/settings'
import { SignInPage } from './routes/sign-in'
import { SignUpPage } from './routes/sign-up'
const router = createMemoryRouter([
{
// Wraps the entire app in the root layout
element: <RootLayout />,
// Mounted where the <Outlet /> component is inside the root layout
children: [
{ path: '/', element: <Home /> },
{ path: '/sign-in', element: <SignInPage /> },
{ path: '/sign-up', element: <SignUpPage /> },
{ path: '/settings', element: <Settings /> },
],
},
])
export default function PopupIndex() {
return <RouterProvider router={router} />
}
Test the integration
- Run your project with the following command:
terminal pnpm dev
- In your Chrome browser, open the extension popup. Ensure that the home page displays with a footer containing the Home, Sign In, and Sign Up links.
- Visit the Sign Up link and ensure the
<SignUp />
component is rendered. - Visit the Sign In link and ensure the
<SignIn />
component is rendered. Sign in with your account. You'll be redirected to the home page and the footer will display the Settings link and the<UserButton />
component. - Select the
<UserButton />
component to open the user menu. - Visit the Settings link and ensure the
<UserProfile />
component is rendered.
Feedback
Last updated on