Skip to Content
Why Treblle
Platform
Trust & Compliance
Pricing
Resources
Company

Treblle Docs

The official Treblle SDK for JavaScript frameworks including Strapi. Seamlessly integrate Treblle to manage communication with your dashboard, send errors, and secure sensitive data.

Treblle with Strapi

To integrate Treblle with Strapi, we provide an official unified SDK for JavaScript frameworks - treblle.

Since Strapi runs on Koa under the hood, you need to define the middleware first and then enable it.

Requirements

  • Node.js: >=18.0.0 (relies on the built-in global fetch)
  • Strapi: 4.x or 5.x

Installation

Install the Treblle JavaScript SDK via NPM :

npm install treblle@^3.0.0

Import the Strapi adapter:

const { strapiTreblle } = require("treblle");

Note

New in v3: per-framework subpath imports let bundlers include only the adapter you use. For Strapi you can import from treblle/strapi:

const { strapiTreblle } = require("treblle/strapi");

Note

This guide is based on the Strapi quickstart project, which you can create with:

npx create-strapi-app my-project --quickstart

Setting up credentials

Create a free account on treblle.com  to get your credentials:

  • sdkToken (SDK Token)
  • apiKey (API Key)

Add these to your .env file:

TREBLLE_SDK_TOKEN=your_sdk_token TREBLLE_API_KEY=your_api_key

Step 1: Create the middleware

Create a new middleware file at middlewares/treblle/index.js:

const { strapiTreblle } = require("treblle"); module.exports = (strapi) => { return { initialize() { strapi.app.use( strapiTreblle({ sdkToken: process.env.TREBLLE_SDK_TOKEN, apiKey: process.env.TREBLLE_API_KEY, }) ); }, }; };

Step 2: Enable the middleware

Enable the middleware in config/middleware.js:

module.exports = { settings: { treblle: { enabled: true, }, }, };

That’s it! Your API requests and responses are now being sent to your Treblle Dashboard. You’ll get features like auto-documentation, real-time request/response monitoring, and error tracking.

Configuration Options

You can pass additional configuration options to strapiTreblle inside your middleware:

const { strapiTreblle } = require("treblle"); module.exports = (strapi) => { return { initialize() { strapi.app.use( strapiTreblle({ sdkToken: process.env.TREBLLE_SDK_TOKEN, apiKey: process.env.TREBLLE_API_KEY, maskedKeywords: ["customSecret", "internalId"], // Optional: Mask additional fields blockedPaths: ["webhooks", "uploads"], // Optional: Skip logging certain paths debug: true, // Optional: Show Treblle errors in console (default: false) ingressEndpoint: "https://ingress-eu.treblle.com", // Optional: Custom ingress endpoint ignoreAdminRoutes: ["admin", "content-manager", "upload"], // Optional: Skip Strapi admin routes }) ); }, }; };

Available options

Option

Description

sdkToken (required)

Your Treblle SDK token

apiKey (required)

Your Treblle API key

maskedKeywords (optional)

Keywords to mask in request/response bodies and headers. Replaces the default keywords - spread DEFAULT_MASKED_KEYWORDS to extend them. Pass [] to turn masking off.

blockedPaths (optional)

Array of path prefixes or RegExp to exclude from logging

debug (optional)

Boolean to show Treblle-related errors in console (default: false)

ingressEndpoint (optional)

Custom Treblle ingress endpoint URL to send data to (default: https://ingress.treblle.com)

ignoreAdminRoutes (optional)

Array of admin route prefixes to ignore (default: ["admin", "content-type-builder", "content-manager"]). Strapi-specific - helps avoid logging internal admin panel requests that are typically not part of your public API.

Note

ignoreAdminRoutes is Strapi-specific. It lets you skip logging internal admin panel requests that are typically not part of your public API.

Choosing where data is sent (data region)

By default the SDK sends all data to https://ingress.treblle.com. If you need your data processed in a specific region, set the ingressEndpoint option to the appropriate Treblle ingress URL:

strapiTreblle({ sdkToken: process.env.TREBLLE_SDK_TOKEN, apiKey: process.env.TREBLLE_API_KEY, ingressEndpoint: "https://ingress-eu.treblle.com", // send data to the EU ingress });

When ingressEndpoint is omitted (or empty), the SDK falls back to the default https://ingress.treblle.com.

Masking sensitive data

Treblle masks sensitive values in request/response bodies and headers before anything leaves your server. Matching is case-insensitive and applies to values of any type. Masking is driven entirely by the maskedKeywords option:

maskedKeywords

Behavior

not set (default)

The built-in default keywords are masked

your own array

Exactly the keywords you list are masked - this replaces the defaults

[] (empty array)

Masking is turned off entirely - bodies and headers are sent as-is

Default masked keywords

When you don’t set maskedKeywords, the following keywords are masked by default:

password, pwd, secret, password_confirmation, passwordConfirmation, cc, card_number, cardNumber, ccv, ssn, credit_score, creditScore, authorization, cookie, set-cookie, x-api-key, api_key, apikey, token, access_token, accessToken, refresh_token, refreshToken, bearer, x-auth-token

Adding to the defaults

Because your array replaces the defaults, extend them by spreading the exported DEFAULT_MASKED_KEYWORDS list rather than listing every default by hand:

const { strapiTreblle, DEFAULT_MASKED_KEYWORDS } = require("treblle"); strapiTreblle({ sdkToken: process.env.TREBLLE_SDK_TOKEN, apiKey: process.env.TREBLLE_API_KEY, maskedKeywords: [...DEFAULT_MASKED_KEYWORDS, "customSecret", "internalId"], });

Turning masking off

Pass an empty array to disable masking completely:

strapiTreblle({ sdkToken: process.env.TREBLLE_SDK_TOKEN, apiKey: process.env.TREBLLE_API_KEY, maskedKeywords: [], // masking disabled });

Caution

With masking off, sensitive request/response body fields and headers - including Authorization, Cookie, API keys and tokens - are sent to Treblle in plaintext. Only disable masking when you are certain no sensitive data flows through the monitored endpoints.

Path blocking examples

Block specific paths or patterns from being logged:

// Block specific paths (string array) blockedPaths: ["admin", "health", "metrics"]; // Block using RegExp for complex patterns blockedPaths: /^\/(admin|health|metrics)/; // Mixed array with strings and RegExp blockedPaths: ["admin", /^\/api\/v1\/internal/];

Tracking database queries

Treblle can show the SQL queries executed during each request (with their execution time) in the data.queries array of the payload. Node has no framework-wide “a query ran” event, so query tracking is opt-in: you wire your database layer’s query event to Treblle’s trackQuery helper once, and every query made during a request is captured automatically. Until you do this, data.queries is simply an empty array.

trackQuery(sql, time) records a query against the request currently in flight (it uses AsyncLocalStorage under the hood, so you don’t need access to req). It is a no-op when called outside of a request.

Caution

Only pass the parameterized SQL string (e.g. SELECT * FROM users WHERE id = $1) - never the parameter bindings. As a safety net, trackQuery also scrubs any inline string/number literals it finds (replacing them with ?).

const { trackQuery } = require("treblle");

Prisma - enable the query event log and forward each event:

const prisma = new PrismaClient({ log: [{ level: "query", emit: "event" }], }); prisma.$on("query", (e) => trackQuery(e.query, e.duration));

Note

Prisma emits query events on an internal async channel, which can lose the request’s context in some setups. If queries don’t appear, prefer a per-request Prisma extension/middleware that calls trackQuery.

Knex - subscribe to its (synchronous, reliable) query events:

const timers = new Map(); knex.on("query", (q) => timers.set(q.__knexQueryUid, process.hrtime.bigint())); knex.on("query-response", (_res, q) => { const start = timers.get(q.__knexQueryUid); const ms = start ? Number(process.hrtime.bigint() - start) / 1e6 : 0; timers.delete(q.__knexQueryUid); trackQuery(q.sql, ms); });

Sequelize - turn on benchmark and forward from the logging callback:

const sequelize = new Sequelize(connectionString, { benchmark: true, // provides the execution time (ms) as the 2nd arg logging: (sql, ms) => trackQuery(sql, ms), });

Adding custom metadata

Attach your own key/value properties to each request - for example user-id, plan, or region - so you can search and filter on them in Treblle. The pairs are sent in the payload as a data.metadata object.

setMetadata works the same way in every framework with no extra setup. Like trackQuery, it uses AsyncLocalStorage under the hood, so you can call it from anywhere during a request without access to req - and it is a no-op when called outside of one. It accepts either a single key/value or an object of pairs:

const { setMetadata } = require("treblle"); app.get("/orders", (req, res) => { setMetadata("user-id", req.user.id); setMetadata({ plan: req.user.plan, region: "eu" }); res.json({ ok: true }); });

To keep the payload small and search-friendly, metadata is limited:

  • Max 20 keys per request (extra new keys are dropped).
  • Keys up to 64 characters (longer keys are truncated).
  • Values must be a string, number, or boolean; strings up to 128 characters (longer values are truncated, unsupported types are dropped).

Caution

Metadata is not masked - values are sent verbatim. Never put secrets, tokens, or sensitive personal data in metadata.

Production-only Setup

Run Treblle only in production by conditionally enabling the middleware in config/middleware.js:

module.exports = { settings: { treblle: { enabled: process.env.NODE_ENV === "production", }, }, };

Debugging

Enable debug mode to see Treblle errors in your console:

strapiTreblle({ sdkToken: process.env.TREBLLE_SDK_TOKEN, apiKey: process.env.TREBLLE_API_KEY, debug: true, });

Tip

For production environments, consider using environment-based configuration to automatically enable or disable debug mode without code changes.

Migrating from v2 to v3

Several configuration options were renamed for clarity and consistency in v3. sdkToken and apiKey keep their names. Update your config:

v2 option

v3 replacement

additionalFieldsToMask

maskedKeywords - same behavior; replaces the defaults, [] turns masking off

blocklistPaths

blockedPaths - same behavior

endpoint

ingressEndpoint - same behavior

ignoreDefaultBlockedPaths

removed - the default blocked paths are now always applied and cannot be disabled

Note

Cloudflare Workers support removed: the moduleWorkerTreblle and serviceWorkerTreblle exports have been removed. If you use Treblle in Cloudflare Workers, stay on treblle@2.x for now - a dedicated web-standards edge SDK is coming as a separate package.

Node.js >=18 required: v3 dropped the node-fetch fallback and relies on the built-in global fetch.

Last updated on