šŸ“ Sign Up | šŸ” Log In

← Root | ↑ Up

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ šŸ“„ shadcn/directory/clerk/clerk-docs/reference/chrome-extension/create-clerk-client │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

╔══════════════════════════════════════════════════════════════════════════════════════════════╗
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘

title: 'createClerkClient()' description: "createClerkClient() allows Chrome Extension developers to access a user's session information or get a token in a service worker." sdk: chrome-extension

The 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.

Usage

The following example:

  • Creates a background service worker that sets up an event listener to handle requests from a content script. If the request wants to interact with Clerk, the listener calls createClerkClient() to create a Clerk instance and refresh the session token, and then calls getToken() to get the token.
  • Adds a link to the home page of the extension that when visited, opens the page as a new tab.
  • The new tab has a button on it that, when clicked, triggers the 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.

<Steps> ### Create your background service worker
  1. In the src/ directory, create the background/ directory.
  2. In the background/ directory, create the index.ts file.
  3. In the 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.
})

Create the tab with the content script

  1. In the src/ directory, create the tabs/ directory.
  2. In the tabs/ directory, create the background-worker-demo.html file.
  3. In the 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>
    
  4. In the tabs/ directory, create the background-worker-demo.tsx file.
  5. In the 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 the extension to open the new tab

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>
    </>
  )
}

Test the background service worker

  1. Run your project with the following command:
    pnpm dev
    
  2. In your Chrome browser, open the extension popup and sign in.
  3. Once you've signed in, select the button that you added and a new tab will open.
  4. In the new tab, select the Get token from service worker button. The token will be displayed on the page. </Steps>

createClerkClient() options

The createClerkClient() function accepts an optional object. The following options are available:

<Properties> - `publishableKey` - `string`

The Clerk Publishable Key for your instance. This can be found on the API keys page in the Clerk Dashboard.


  • syncHost?
  • string

The host to sync the session with. For more information, see the dedicated guide. </Properties>

ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•

← Root | ↑ Up