Docs

Integrate Fauna with Clerk

You will learn the following:

  • Configure Fauna to accept JWTs from Clerk
  • Create a JWT template in Clerk to generate Fauna JWTs
  • Use the Fauna JWTs to authenticate Fauna queries in your Next.js app

Important

See the demo repo for a full example of how to integrate Fauna with Clerk in a Next.js app.

Integrating Fauna with Clerk gives you the benefits of using a Fauna database while leveraging Clerk's authentication, prebuilt components, and webhooks.

This guide will walk you through the steps to integrate Fauna with Clerk in your Next.js app.

.env.local
NEXT_PUBLIC_CLERK_FRONTEND_API_URL=YOUR_FRONTEND_API_URL
NEXT_PUBLIC_CLERK_JWKS_URL=YOUR_JWKS_URL

Configure Fauna

  1. Navigate to the Fauna Dashboard and select your database.
  2. Select the Access Providers tab and select Create Access Provider.
  3. Fill out the form:
    • Enter a Name for the access provider, such as Clerk.
    • Copy and save the Audience URL. You will need this later.
    • In Issuer, paste the Clerk Frontend API URL you copied in the previous step. Do not include a trailing slash (/).
    • In JWKS Endpoint, paste the Clerk JWKS URL you copied in the previous step.
    • Select Create.
  4. Select the access provider that you just created.
  5. Update the access provider's FSL schema to include a user-defined role. For example:
    access provider Clerk {
      // Don't change the values of the issuer or jwks_uri fields.
      issuer "..."
      jwks_uri "..."
    
      // Adds a user-defined role to Clerk JWTs.
      role <YOUR_ROLE>
    }
  6. Select Save.

Create a JWT template in Clerk

Clerk's JWT templates allow you to generate a new valid Fauna authentication token (JWT) for each signed in user. These tokens allow authenticated users to access your data with Fauna's API.

To create a JWT template for Fauna:

  1. In the Clerk Dashboard, navigate to the JWT templates page.
  2. Select the New template button, then select Fauna from the list of options.
  3. Configure your template:
    • The value of the Name field will be required when using the template in your code. For this tutorial, name it fauna.
    • You can leave all other fields as their default settings or customize them to your needs. See the JWT template guide to learn more about these settings.
    • In the Claims section, set the aud claim to the Audience URL you copied from Fauna in Step 2. The URL format should be https://db.fauna.com/db/<YOUR_FAUNA_DB_ID>. You can include additional claims if you’d like, but aud is the only required one. Shortcodes are available to make adding dynamic user values easy.
    • Select Save from the notification bubble to complete setup.

Install the Fauna library

Add the Fauna library to your project.

terminal
npm i fauna
terminal
yarn add fauna
terminal
pnpm add fauna

Authenticate Fauna queries in your Next.js app

You can now create Fauna JWTs in Clerk using the JWT template you created in the previous step. Generate the Fauna JWT by calling Clerk's useAuth().getToken method, and use it to authenticate with Fauna as an end user, as shown in the following example:

app/page.tsx
'use client'

import React from 'react'
import { useAuth } from '@clerk/nextjs'
import { Client, fql } from 'fauna'

export default function Page() {
  const [message, setMessage] = React.useState('')
  // The `useAuth()` hook is used to get the `getToken()` method.
  const { getToken } = useAuth()

  // Create a function to make a query to Fauna.
  const makeQuery = async () => {
    let client

    try {
      // Get the custom Fauna token from Clerk.
      const clerkToken = await getToken({ template: 'fauna' })

      if (!clerkToken) {
        setMessage('No token found')
        return
      }

      // Initialize a new Fauna client with the Clerk token.
      client = new Client({ secret: clerkToken })

      // Make a query to Fauna.
      const response = await client.query(fql`'Hello World!'`)
      setMessage(JSON.stringify(response))
    } catch (error) {
      console.error(error)
      setMessage('Error occurred')
    } finally {
      if (client) client.close()
    }
  }

  return (
    <>
      <button onClick={makeQuery}>Make authenticated query</button>
      <p>Message: {message}</p>
    </>
  )
}

Note

The getToken({ template: <your-template-name> }) call is asynchronous and returns a Promise that needs to be resolved before accessing the token value. This token is short-lived for better security and should be called before every request to your Fauna database. The caching and refreshing of the token are handled automatically by Clerk.

Feedback

What did you think of this content?

Last updated on