Skip to content

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.

  1. Install Sentry’s React SDK

    Terminal window
    pnpm add @sentry/react --filter frontend
  2. 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,
    });
  3. Import and update your main.tsx entry point

    import './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 />
    );
  4. 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 Sentry
    if (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>
    <button
    onClick={() => 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;
  5. Update your App.tsx to include Sentry Error Boundary and React Router

    // previous imports
    import * as Sentry from '@sentry/react';
    import ErrorBoundary from './components/ErrorBoundary';
    const SentryRoutes = Sentry.withSentryReactRouterV7Routing(Routes);
    // Protected route component
    const 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;
  6. 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 sourcemaps

    This 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.

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)

  1. Install Sentry SDK for Node.js

    Terminal window
    pnpm add @sentry/node --filter server
  2. 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,
    });
  3. 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);
  4. Use Sentry’s Wizard again to setup sourcemaps in the server project

    Terminal window
    cd apps/server && pnpx @sentry/wizard@latest -i sourcemaps

    The prompts will be the same, with the only difference this time being that we’ll select esbuild instead of Vite.

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.

Terminal window
pnpm dev

Once that’s loaded, you can browse to http://localhost:5173 to view Sentry Academy.

Academy