Sviluppo web
Sentry in Next.js: il minimo utile per non perdere errori
Wizard, `instrumentation.ts` e `global-error.tsx`: gli errori di server e client arrivano con stack trace, senza spedire cookie e senza bruciare la quota.
In sintesi
- Il wizard crea `instrumentation.ts`, `instrumentation-client.ts` e modifica `next.config.ts`: controlla il diff prima del commit, con l'SDK MIT alla 11.10.0.
- `onRequestError` collega gli errori di route a Sentry; `app/global-error.tsx` copre gli errori di rendering che sfuggono ai boundary di segmento.
- `tracesSampleRate` campiona le transazioni, non gli errori: `ignoreErrors` e il filtro sui cookie vanno impostati prima di mandare dati reali.
Risposta breve: esegui npx @sentry/wizard@latest -i nextjs, imposta SENTRY_DSN e inizializza l'SDK in instrumentation.ts; per gli errori di rendering aggiungi app/global-error.tsx. Da lì ogni eccezione arriva con stack trace e route.
Il wizard e cosa scrive
npx @sentry/wizard@latest -i nextjs
npx next build
Il wizard crea instrumentation.ts e instrumentation-client.ts, avvolge next.config.ts con withSentryConfig e scrive il DSN in .env.local. Leggi il diff prima di committare: la configurazione predefinita include l'upload delle source map.
Server: instrumentation.ts
import * as Sentry from "@sentry/nextjs";
export async function register() {
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV,
tracesSampleRate: 0.1,
});
}
export const onRequestError = Sentry.captureRequestError;
onRequestError è l'hook che Next.js chiama sugli errori di route: senza, gli errori lato server restano nei log e non diventano eventi. tracesSampleRate: 0.1 tiene il 10% delle transazioni, non degli errori.
Client: global-error.tsx
"use client";
import * as Sentry from "@sentry/nextjs";
export default function GlobalError({ error }: { error: Error }) {
Sentry.captureException(error);
return (
Something went wrong.
);
}
Questo file intercetta gli errori di rendering che sfuggono agli error boundary di segmento e sostituisce l'intera pagina. captureException va chiamato prima del return: un errore durante il render non dà una seconda occasione.
Cosa filtrare prima che sia troppo tardi
Sentry.init({
dsn: process.env.SENTRY_DSN,
ignoreErrors: [/ResizeObserver loop/, /^NetworkError$/],
beforeSend(event) {
if (event.request?.headers) delete event.request.headers.cookie;
return event;
},
});
ResizeObserver e NetworkError sono rumore noto: riempiono la quota senza indicare un bug. Il filtro su headers.cookie evita di spedire sessioni al servizio, ed è un obbligo prima di mandare dati di utenti reali.
Limite dichiarato
Sentry è un servizio esterno: l'SDK è MIT, il servizio ospitato no. Ogni evento lascia la tua infrastruttura, quindi scegliere cosa inviare e per quanto conservarlo resta una tua responsabilità. L'alternativa self-hosted esiste ed è più onerosa da mantenere.
Dove continuare
Nel catalogo parti dalla libreria shadcn, dal record alert toast e dallo skeleton animato. Per il resto leggi gli error boundary in App Router, gli errori di build comuni e il confronto analytics Vercel o self-hosted.
Domande frequenti
Sentry è obbligatorio per un progetto Next.js?
No. Senza servizio esterno puoi loggare gli errori su stdout e raccoglierli dall'hosting. Sentry aggiunge raggruppamento, stack trace con source map e avvisi, che è il lavoro che altrimenti fai a mano.
Dove va la chiave DSN?
In una variabile d'ambiente, mai nel codice o nel repository. Il DSN identifica il progetto e accetta eventi: chi lo ottiene può inviare dati alla tua quota.
Perché alcuni errori lato server non arrivano?
Quasi sempre perché manca onRequestError in instrumentation.ts o perché il file non è nella radice del progetto. Senza quell'hook Next.js registra l'errore e non lo inoltra all'SDK.
Come evito di esaurire la quota?
Con ignoreErrors per il rumore noto, un sample rate basso sulle transazioni e gli avvisi solo su errori nuovi. La quota si consuma sugli eventi, non sulle richieste: un loop di errori la brucia in poche ore.
Posso ospitare Sentry da solo?
Sì, il progetto è open source e self-hostable, ma richiede più servizi e manutenzione continua. Per un team piccolo il servizio ospitato costa meno del tempo di gestione.