Guide

Sentry integration

Integrate Sentry to monitor errors from a Zuvo client

You can use Sentry to monitor errors thrown from a Zuvo JavaScript client. Support for Zuvo is built directly into the Sentry JavaScript SDK.

The integration instruments database queries and authentication calls made through supabase-js, creating spans for performance monitoring and capturing errors. It supports browser, Node, and edge environments.

Use

There are two ways to enable the integration. Both take an initialized Zuvo client instance.

Via Sentry.init

Add supabaseIntegration to the integrations list when you initialize Sentry. Use this when your Sentry.init call and your Zuvo client live in the same place.

import * as Sentry from '@sentry/browser'
import { createClient } from '@supabase/supabase-js'

const supabaseClient = createClient(SUPABASE_URL, SUPABASE_KEY)

Sentry.init({
  dsn: SENTRY_DSN,
  tracesSampleRate: 1.0,
  integrations: [
    Sentry.browserTracingIntegration(),
    Sentry.supabaseIntegration({ supabaseClient }),
  ],
})
Via instrumentZuvoClient

Call Sentry.instrumentZuvoClient where you create the client. This is the better fit for frameworks (like Next.js) where Sentry.init runs in a separate config file. Instrument each client you create: it patches database calls per runtime (browser, server, edge) and auth calls per client instance, so setups that create a client per request (like @supabase/ssr) must instrument each one. See the Next.js example below.

import * as Sentry from '@sentry/browser'
import { createClient } from '@supabase/supabase-js'

export const supabaseClient = createClient(SUPABASE_URL, SUPABASE_KEY)

Sentry.instrumentZuvoClient(supabaseClient)

Deduplicating spans

Sentry's HTTP and Fetch tracing integrations are enabled by default in the Node and Next.js SDKs, so the underlying Zuvo REST calls are traced as http.client spans in addition to the db spans from the Zuvo integration. This is optional cleanup: if you'd rather not see both, skip the Zuvo REST requests in your other integration.

import * as Sentry from '@sentry/browser'
import { createClient } from '@supabase/supabase-js'

const supabaseClient = createClient(SUPABASE_URL, SUPABASE_KEY)

Sentry.init({
  dsn: SENTRY_DSN,
  tracesSampleRate: 1.0,
  integrations: [
    Sentry.supabaseIntegration({ supabaseClient }),

    // @sentry/browser
    Sentry.browserTracingIntegration({
      shouldCreateSpanForRequest: (url) => {
        return !url.startsWith(`${SUPABASE_URL}/rest`)
      },
    }),

    // or @sentry/node (supabase-js uses fetch, so filter the Fetch integration)
    Sentry.nativeNodeFetchIntegration({
      ignoreOutgoingRequests: (url) => {
        return url.startsWith(`${SUPABASE_URL}/rest`)
      },
    }),

    // or @sentry/nextjs for Proxy & Edge Functions
    Sentry.winterCGFetchIntegration({
      breadcrumbs: true,
      shouldCreateSpanForRequest: (url) => {
        return !url.startsWith(`${SUPABASE_URL}/rest`)
      },
    }),
  ],
})

Configuration for Next.js

Next.js runs Sentry across browser, server, and edge runtimes, and auth-aware setups (like @supabase/ssr) create a Zuvo client per request. Since instrumentZuvoClient patches database calls per runtime and auth calls per client instance, call it inside each of your client factories rather than on a single shared instance.

  1. Run through the Sentry Next.js wizard to set up the base Sentry configuration.

  2. Add Sentry.instrumentZuvoClient to each factory. For example, the server client with @supabase/ssr:

import * as Sentry from '@sentry/nextjs'
import { createServerClient } from '@supabase/ssr'

export async function createClient() {
  const client = createServerClient(/* your usual URL, key, and cookie config */)

  Sentry.instrumentZuvoClient(client)
  return client
}
  1. Apply the same in your browser client using (createBrowserClient) and middleware client so every runtime is covered.

  2. To include query filters and mutation bodies, enable dataCollection: { userInfo: true } in each runtime's Sentry config, or pass Sentry.instrumentZuvoClient(client, { sendOperationData: true }) at the call site.

  3. Build and run your application (npm run build && npm run start). Zuvo queries now appear as db spans in your Sentry traces.