Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Integrating Sentry for Full-Stack Error Tracking

Hello! Welcome to your next lesson.

In our last session, we successfully deployed our containerized Tanstack Start application to Fly.io, making it a live, publicly accessible service. Now that our application is running in a production environment, our focus shifts to maintaining its health and reliability.

Today, we'll address a critical aspect of production readiness: observability. The learning outcome for this lesson is to integrate a third-party error tracking service (e.g., Sentry) to capture both client and server-side errors. An SSR application has two primary execution contexts—the server and the client—and errors can occur in either. A robust error tracking setup is essential for diagnosing and resolving issues quickly, regardless of where they originate.

We will use Sentry, a popular application monitoring platform, to instrument our Tanstack Start application, ensuring that we have full visibility into any exceptions that occur in production.

1. The Value of Comprehensive Error Tracking

Before we dive into the implementation, it's important to understand what a tool like Sentry provides beyond a simple console.log. In a distributed environment like an SSR application, an error on the server might cause a hydration mismatch on the client, or a client-side issue might only manifest for users with a specific browser. Tracking these issues manually is difficult.

Sentry aggregates errors from both environments and enriches them with valuable context, such as the user's browser, the request details, and a complete stack trace mapped to your original source code.

To see what this looks like in practice, let's watch a detailed overview. While the video uses Next.js, the Sentry features and dashboard are identical, and the architectural principles of client/server error capture are directly transferable to our Tanstack Start application.

Sentry + Next.js | Essential Error Monitoring

The video 'Sentry + Next.js | Essential Error Monitoring' from the Michael Guay channel provides an excellent demonstration of Sentry's capabilities. Focus on what Sentry offers, not the Next.js-specific setup wizard.

Please watch two key sections: Introduction (00:00 - 01:06): To get a high-level overview of why Sentry is valuable. Exploring Sentry Dashboard Features (16:18 - 23:20): This is the most important part. Pay close attention to features like source-mapped stack traces, session replay, breadcrumbs, and performance tracing. These are the features we are aiming to enable in our own application.

As you saw, Sentry gives you a powerful toolkit for post-deployment debugging, including:

  • Source-Mapped Stack Traces: See the exact line of your TypeScript code that caused an error, even in a minified production bundle.
  • Session Replay: Watch a video-like replay of the user's interactions leading up to an error.
  • Breadcrumbs: A timeline of application events (UI clicks, network requests) that provide context for the error.
  • Distributed Tracing: Connect a frontend error to the backend API call that may have triggered it.

2. Sentry Integration for TanStack Start

Now, let's integrate Sentry into our application. We will follow the official Sentry documentation for TanStack Start, which provides the most accurate and up-to-date instructions.

First, you'll need to create a free Sentry account at sentry.io and create a new project. When asked to choose a platform, select TanStack Start (React). Sentry will then provide you with a DSN (Data Source Name), which is a unique key for your project. Keep this handy; you'll need it shortly.

Our primary resource for the implementation will be the official Sentry guide.

Sentry Docs: TanStack Start React

This is the official Sentry documentation for TanStack Start with React. We will follow it closely to configure both client-side and server-side monitoring.

We will work through this document step-by-step. For now, just have it open and ready. We'll start with Step 1: Install, and then move to Step 2: Configure.

Step 2.1: Install the SDK

As per the documentation, add the Sentry SDK to your project.

npm install @sentry/tanstackstart-react --save

Step 2.2: Configure Client-Side Sentry

We'll initialize Sentry for the client inside src/router.tsx. This file is a central point in a Tanstack Start app and is executed in both server and client contexts. Therefore, we must ensure the client-side Sentry.init call only runs in the browser.

Read the "Configure Client-Side Sentry" section of the Sentry documentation (a5b5a) and add the provided code to your src/router.tsx file.

Key points about this configuration:

  • if (!router.isServer): This conditional check is crucial. It ensures that Sentry's browser-specific integrations (like session replay) are only initialized on the client.
  • dsn: This is where you'll paste the DSN from your Sentry project. It's best practice to manage this via an environment variable (e.g., VITE_SENTRY_DSN).
  • integrations: This array is where you enable Sentry features.
    • Sentry.tanstackRouterBrowserTracingIntegration(router) automatically instruments your application for performance monitoring, creating traces for navigations.
    • Sentry.replayIntegration() enables the Session Replay feature we saw in the video.
  • tracesSampleRate and replaysSessionSampleRate: These control how much data is captured. 1.0 means 100%, which is fine for development but should be lowered in high-traffic production environments to manage costs.

Step 2.3: Configure Server-Side Sentry

Next, we need to capture errors that happen on the server during rendering or in your API routes. This requires a separate initialization.

Follow the "Configure Server-side Sentry" section of the documentation (a5b5a). This involves two parts:

  1. Create instrument.server.mjs: Create this file in the root of your project. It will contain the Sentry.init call for the Node.js environment. Notice it has fewer integrations, as browser-specific features like session replay don't apply here.

  2. Update package.json scripts: The server-side instrumentation needs to be loaded before your application code runs. We achieve this using Node.js's --import flag. Modify your dev and start scripts as shown in the documentation.

    // package.json
    "scripts": {
      "dev": "NODE_OPTIONS='--import ./instrument.server.mjs' vite dev --port 3000",
      "start": "node --import ./.output/server/instrument.server.mjs .output/server/index.mjs",
      // ... other scripts
    }
    

    Also, remember to add the build step to copy the instrumentation file to your output directory, which is essential for your production deployment on Fly.io.

    // package.json
    "scripts": {
        "build": "vite build && cp instrument.server.mjs .output/server",
        // ...
    }
    

This setup ensures that the Sentry SDK is active and ready to catch exceptions as soon as your server process starts.

3. Capturing and Verifying Errors

With the SDK configured, Sentry will automatically capture unhandled exceptions on the client. However, there are cases where you need to report errors manually.

Capturing Errors in Error Boundaries

As noted in the documentation (a5b5a, part 3), errors caught by Tanstack Router's errorComponent are considered "handled" and won't be sent to Sentry automatically. You must capture them explicitly. This is a perfect use case for combining Sentry with the error boundaries we learned about in Module 1.

Update any route's errorComponent to report the error to Sentry:

// Example: src/routes/index.tsx
import { createRoute } from '@tanstack/react-router'
import * as Sentry from "@sentry/tanstackstart-react";
import { useEffect } from 'react';

// ... route definition

export const Route = createRoute({
  // ...
  errorComponent: ({ error }) => {
    useEffect(() => {
      Sentry.captureException(error);
    }, [error]);

    return <div>Something went wrong!</div>;
  },
});

Capturing Server-Side Errors

The documentation also states that automatic error monitoring for server functions is not yet supported. This means you should manually wrap your server-side logic (e.g., in route loaders or server functions) in try...catch blocks and call Sentry.captureException(error) in the catch block to report server-side failures.

Verification

Now, let's confirm everything is working.

Sentry Docs: TanStack Start React - Verify

The 'Verify' section of the Sentry documentation provides simple code snippets to test both client and server error capturing.

Follow the instructions in this section. Add the test button to a page to trigger a frontend error, and create the test API route to trigger a backend error. After triggering both, check your project in Sentry to see the issues appear.

After adding the test code and clicking the button, you should see two new issues appear in your Sentry dashboard:

  1. A frontend error, Sentry Example Frontend Error.
  2. A backend error, Sentry Example Route Error.

Click into these issues to explore the context, tags, and stack traces that Sentry has automatically collected. If you configured tracing, you should also be able to see the full trace connecting the frontend fetch to the backend error.

Conclusion

In this lesson, you have integrated a professional-grade error monitoring service into your Tanstack Start application, giving you crucial visibility into the health of your application in production.

Key Takeaways:

  • Error monitoring is essential for SSR applications to capture issues from both the client and server contexts.
  • Sentry integration in Tanstack Start requires separate initialization for the client (in router.tsx behind an !isServer check) and the server (in a dedicated instrument.server.mjs file).
  • Server-side instrumentation is loaded using the NODE_OPTIONS='--import ...' flag in your package.json scripts, a modern approach for ESM-based Node.js applications.
  • While Sentry captures many errors automatically, you must manually report handled errors, such as those caught by Tanstack Router's errorComponent, using Sentry.captureException().

With error tracking in place, you can deploy with greater confidence. However, errors are only part of the story. Sometimes, you need to understand the application's behavior even when things don't break.

In our next lesson, we will implement structured logging for server-side operations and errors. This will complement Sentry by providing a detailed, searchable record of application events, which is invaluable for debugging complex business logic and performance issues.

Can't find a good explanation? Sign up and we'll make it for you

Sign up