āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā š shadcn/directory/clerk/clerk-docs/reference/chrome-extension/create-clerk-client ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
createClerkClient()'
description: "createClerkClient() allows Chrome Extension developers to access a user's session information or get a token in a service worker."
sdk: chrome-extensionThe createClerkClient() helper initializes a new Clerk instance on demand and refreshes the session token if there is a valid, signed-in user. It can be used in a background service worker to access a user's information or session token.
When a side panel or a popup is closed, the Clerk process that normally refreshes the user's session token every 60 seconds is no longer running, and the stored session will become stale. If a request were made 60 seconds after the side panel or popup was closed, it would fail because the session token is no longer valid. By configuring createClerkClient() to run in a background service worker, you can ensure that the user's session is always fresh.
The following example:
createClerkClient() to create a Clerk instance and refresh the session token, and then calls getToken() to get the token.<Steps> ### Create your background service worker[!WARNING] The following example assumes that you have followed the Chrome Extension Quickstart and then the Add React Router guide, but you can apply these concepts to your own application.
src/ directory, create the background/ directory.background/ directory, create the index.ts file.index.ts file, paste the following code to create an event listener that listens for messages from content scripts and calls a function that uses createClerkClient() to get a new token for the user.import { createClerkClient } from '@clerk/chrome-extension/background'
const publishableKey = process.env.PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY
if (!publishableKey) {
throw new Error('Please add the PLASMO_PUBLIC_CLERK_PUBLISHABLE_KEY to the .env.development file')
}
// Use `createClerkClient()` to create a new Clerk instance
// and use `getToken()` to get a fresh token for the user
async function getToken() {
const clerk = await createClerkClient({
publishableKey,
})
// If there is no valid session, then return null. Otherwise proceed.
if (!clerk.session) {
return null
}
// Return the user's session
return await clerk.session?.getToken()
}
// Create a listener to listen for messages from content scripts
// It must return true, in order to keep the connection open and send a response later.
// NOTE: A runtime listener cannot be async.
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
// This example sends the token back to the content script
// but you could also use the token to perform actions on behalf of the user
getToken()
.then((token) => sendResponse({ token }))
.catch((error) => {
console.error('[Background service worker] Error:', JSON.stringify(error))
// If there is no token then send a null response
sendResponse({ token: null })
})
return true // REQUIRED: Indicates that the listener responds asynchronously.
})
src/ directory, create the tabs/ directory.tabs/ directory, create the background-worker-demo.html file.background-worker-demo.html file, paste the following code to create a basic HTML file that will house the React component for the content script.
<!doctype html>
<html>
<head>
<title>Clerk Background Worker Demo</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body></body>
</html>
tabs/ directory, create the background-worker-demo.tsx file.background-worker-demo.tsx file, paste the following code to create a React component with a button that will trigger the background service worker to get the token. If the token is returned, it will be displayed on the page.
import * as React from 'react'
export default function NewTab() {
const [token, setToken] = React.useState<string | null>(null)
const getToken = async (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault()
// Trigger the background service worker to get the token
// and set the token in the state
chrome.runtime.sendMessage({ greeting: 'get-token' }, (response) => {
setToken(response.token)
})
}
return (
<div>
<p>Clerk Background Worker Demo</p>
<div className="App">
<p>
This new tab simulates a content page where you might want to access user information, or
make a request to your backend server and include a user token in the request.
</p>
<p>Make sure that you are signed into the extension. You can have the popup closed.</p>
<button type="button" onClick={getToken} className="button invert">
Get token from service worker
</button>
{token && <p>Token: {token}</p>}
</div>
</div>
)
}
Add a button to your Chrome Extension to open the page you created in the previous step as a new tab. This can be added anywhere in your extension. The following example places the button on the home page of the extension.
export const Home = () => {
return (
<>
<h1>Clerk + Chrome Extension</h1>
<button
onClick={() => {
chrome.tabs.create({
url: './tabs/background-worker-demo.html',
})
}}
>
Open background worker demo in a new tab
</button>
</>
)
}
pnpm dev
createClerkClient() optionsThe createClerkClient() function accepts an optional object. The following options are available:
The Clerk Publishable Key for your instance. This can be found on the API keys page in the Clerk Dashboard.
syncHost?stringThe host to sync the session with. For more information, see the dedicated guide. </Properties>
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā