Add React Router to your Clerk-powered Chrome Extension
You will learn the following:
- Install
react-router
- 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. It assumes you're using Plasmo to build your Chrome Extension.
Install react-router
React Router is a lightweight, fully-featured routing library. To install it in your project, run the following command:
pnpm add react-router
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
. 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'
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'
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