Skip to main content

Turbopack

1. Initialize Client

instrumentation-client.ts
import {
init,
events,
markers,
network,
vitals,
profiler,
paint,
tag,
} from "@palette.dev/browser";


init({
key: process.env.NEXT_PUBLIC_PALETTE_CLIENT_KEY!,
plugins: [
events(),
network(),
vitals(),
markers(),
profiler(),
paint({ componentPaint: true }),
],
});

// Start profiler on user interactions
profiler.on(
[
"paint.click",
"paint.keydown",
"paint.scroll",
"paint.mousemove",
"markers.measure",
"events.load",
"events.dcl",
],
{
sampleInterval: 1,
maxBufferSize: 100_000,
}
);

export function onRouterTransitionStart(url: string) {
tag("palette.location", url);
}

Palette requires the version parameter to be passed to init when using Turbopack:

init({
// ...
version: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA ?? "local",
});

2. Configure Headers and Source Maps

Ensure your next.config.js generates source maps in production and has profiling headers:

next.config.js
import { NextConfig } from "next";

/** @type {import('next').NextConfig} */
const nextConfig: NextConfig = {
productionBrowserSourceMaps: true,
async headers() {
return [
{
source: "/(.*)", // apply to all routes
headers: [
{
key: "Document-Policy",
value: "js-profiling",
},
],
},
];
},
};

export default nextConfig;

3. Post-build Source Maps Upload

Use the palette upload command to upload source maps after building your Next.js application. You can add this command to your package.json scripts:

package.json
{
"scripts": {
"build": "next build && palette upload .next/static --release"
}
}
© 2025 Redraw, Inc.