Getting Started with Sentry
In this module, you’ll learn how to set up Sentry monitoring in your fullstack JavaScript application. We’ll configure Error Monitoring, Logging, Session Replays, and Tracing for both the Vite React (alongside React Router 7) frontend and the Node.js backend to give you complete visibility into your application’s behavior.
Learning Objectives
By the end of this module, you will:
- Set up Sentry Error Monitoring for both frontend and backend
- Configure Session Replays to debug user interactions
- Implement structured logging across your application
- Set up distributed tracing to track request flows
- Create your first traces and spans with meaningful context
What is Sentry?
Sentry is an error monitoring and performance monitoring platform that helps developers identify, debug, and resolve issues in their applications. Key features include:
- Error Monitoring: Automatic error detection and alerting
- Session Replays: Visual recordings of user sessions when errors occur
- Performance Monitoring: Distributed tracing and performance insights
- Logging: Structured log collection and analysis
Setting Up Sentry in Your Frontend (Vite + React + React Router 7)
Before you get into the next steps, you should create your frontend and server projects inside your sentry account.
You’ll need to take note of your Sentry DSNs along the way, which you receive when you configure the projects.
Select React
and Node.js
as the platforms respectively.
-
Install Sentry’s React SDK
Terminal window pnpm add @sentry/react --filter frontend -
Initialize Sentry
Create
./apps/frontend/src/instrument.ts
:import * as Sentry from "@sentry/react";import { useEffect } from "react";import { useLocation, useNavigationType, createRoutesFromChildren, matchRoutes } from "react-router-dom";Sentry.init({dsn: '<Your Sentry DSN>',sendDefaultPii: true,integrations: [Sentry.browserTracingIntegration(),Sentry.replayIntegration(),Sentry.reactRouterV7BrowserTracingIntegration({useEffect: useEffect,useLocation,useNavigationType,createRoutesFromChildren,matchRoutes,}),],_experiments: {enableLogs: true,},tracesSampleRate: 1.0,tracePropagationTargets: ["localhost:3001"],replaysSessionSampleRate: 1.0,replaysOnErrorSampleRate: 1.0,}); -
Import and update your
main.tsx
entry pointimport './instrument.js';import { createRoot } from 'react-dom/client';import * as Sentry from '@sentry/react';import App from './App.tsx';import './index.css';createRoot(document.getElementById('root')!, {onUncaughtError: Sentry.reactErrorHandler((error, errorInfo) => {console.warn('Uncaught error', error, errorInfo.componentStack);}),onCaughtError: Sentry.reactErrorHandler(),onRecoverableError: Sentry.reactErrorHandler(),}).render(<App />); -
Create your ErrorBoundary
Create
./apps/frontend/src/components/ErrorBoundary.tsx
:import * as Sentry from '@sentry/react';import { useRouteError, isRouteErrorResponse } from 'react-router-dom';import React from 'react';const ErrorBoundary = () => {const error = useRouteError();React.useEffect(() => {// Send route errors to Sentryif (error) {Sentry.captureException(error);}}, [error]);if (isRouteErrorResponse(error)) {return (<div className="min-h-screen flex items-center justify-center bg-gray-50"><div className="text-center"><h1 className="text-4xl font-bold text-red-600 mb-4">{error.status}</h1><p className="text-xl text-gray-600 mb-4">{error.statusText}</p><p className="text-gray-500">{error.data}</p></div></div>);}return (<div className="min-h-screen flex items-center justify-center bg-gray-50"><div className="text-center"><h1 className="text-2xl font-bold text-red-600 mb-4">Something went wrong</h1><p className="text-gray-600 mb-4">{error instanceof Error ? error.message : 'Unknown error occurred'}</p><buttononClick={() => window.location.reload()}className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">Reload page</button></div></div>);};export default ErrorBoundary; -
Update your
App.tsx
to include Sentry Error Boundary and React Router// previous importsimport * as Sentry from '@sentry/react';import ErrorBoundary from './components/ErrorBoundary';const SentryRoutes = Sentry.withSentryReactRouterV7Routing(Routes);// Protected route componentconst ProtectedRoute: React.FC<{ children: React.ReactNode }> = ({ children }) => {const { isAuthenticated, isLoading } = useAuth();if (isLoading) {return <div>Loading...</div>;}if (!isAuthenticated) {return <Navigate to="/login" replace />;}return <>{children}</>;};function App() {return (<AuthProvider><UserStateProvider><Router><SentryRoutes><Route path="/login" element={<LoginPage />} errorElement={<ErrorBoundary />} /><Route path="/" element={<MainLayout />}><Route index element={<ProtectedRoute><HomePage /></ProtectedRoute>} /><Route path="courses" element={<ProtectedRoute><CoursesPage /></ProtectedRoute>} errorElement={<ErrorBoundary />} /><Route path="courses/:courseId" element={<ProtectedRoute><CourseDetailPage /></ProtectedRoute>} errorElement={<ErrorBoundary />} /><Route path="my-courses" element={<ProtectedRoute><MyCoursesPage /></ProtectedRoute>} errorElement={<ErrorBoundary />} /><Route path="favorites" element={<ProtectedRoute><FavoritesPage /></ProtectedRoute>} errorElement={<ErrorBoundary />} /><Route path="lesson-plans" element={<ProtectedRoute><LessonPlansPage /></ProtectedRoute>} errorElement={<ErrorBoundary />} /><Route path="profile" element={<ProtectedRoute><ProfilePage /></ProtectedRoute>} errorElement={<ErrorBoundary />} /></Route><Route path="*" element={<Navigate to="/" replace />} errorElement={<ErrorBoundary />} /></SentryRoutes></Router></UserStateProvider></AuthProvider>);}export default App; -
Setup the Vite plugin with Sentry’s Wizard
We can use Sentry’s wizard to help us setup the Vite plugin. The Vite plugin takes care of the sourcemaps for us.
Terminal window cd apps/frontend && pnpx @sentry/wizard@latest -i sourcemapsThis will trigger a series of prompts:
- Select
Yes
if you get notified about uncommited files - Select
Sentry SaaS
when you get asked about what type of Sentry account you have - Select
Yes
if you already have a Sentry account - This will open a browser window that lets you select your organization and project
- Once you do, you’re back to the terminal and you’ll be prompted about the bundler, so select
Vite
- Select
PNPM
as the package manager - Select
No
when asked about using a CI/CD tool
That’s it! The
vite.config.ts
file will be updated, and you’ll see a.env.sentry-build-plugin
file next to your.env
file.Now when we build our frontend, the Vite plugin will automatically upload the sourcemaps to Sentry an link them to our project and release.
- Select
These configurations will setup your React frontend to leverage all of Sentry’s core capabilities and ensure you’re capturing Errors, Traces, Logs, and Replays within your frontend application. Let’s move onto the backend.
Configuring Sentry in your Backend (Node.js)
-
Install Sentry SDK for Node.js
Terminal window pnpm add @sentry/node --filter server -
Configure Sentry in your Node.js Server
Create
instrument.ts
in your server directory:import * as Sentry from '@sentry/node';Sentry.init({dsn: '<Your Sentry DSN>',_experiments: {enableLogs: true,},debug: true,tracesSampleRate: 1.0,}); -
Add instrument.ts to your server entry point - index.ts
import './instrument';import * as Sentry from '@sentry/node';// Add this after all routes,// but before any and other error-handling middlewares are defined.Sentry.setupExpressErrorHandler(app); -
Use Sentry’s Wizard again to setup sourcemaps in the server project
Terminal window cd apps/server && pnpx @sentry/wizard@latest -i sourcemapsThe prompts will be the same, with the only difference this time being that we’ll select
esbuild
instead ofVite
.
With these configurations in place, you’ve now got Sentry setup to monitor your application across both the frontend and server side implementations.
If you are running your application currently, it might be a good idea to toss a restart on it after all of these configurations.
pnpm dev
Once that’s loaded, you can browse to http://localhost:5173 to view Sentry Academy.
