Skip to main content
The @sentry/nuxt package provides comprehensive error tracking and performance monitoring for Nuxt applications, with support for both client and server environments.

Prerequisites

  • Node.js 18.19.1 or newer
  • Nuxt 3.7.0 or newer (3.14.0+ recommended) or Nuxt 4.x
  • A Sentry account and project DSN
Nuxt 3.14.0+ is recommended for the best experience. Older versions are supported but may have limitations.

Installation

1

Install the Package

Install @sentry/nuxt using your preferred package manager:
npm install @sentry/nuxt
Current Version: 10.42.0
2

Register the Sentry Module

Add the Sentry module to your nuxt.config.ts:
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@sentry/nuxt/module'],
  
  sentry: {
    // Optional: Sentry configuration
    dsn: 'YOUR_DSN_HERE',
  },
});
3

Create Client Configuration

Create sentry.client.config.ts in your project root:
import * as Sentry from '@sentry/nuxt';

Sentry.init({
  dsn: 'YOUR_DSN_HERE',
  
  integrations: [
    Sentry.replayIntegration(),
  ],
  
  tracesSampleRate: 1.0,
  
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
});
4

Create Server Configuration

Create sentry.server.config.ts in your project root:
import * as Sentry from '@sentry/nuxt';

Sentry.init({
  dsn: 'YOUR_DSN_HERE',
  
  tracesSampleRate: 1.0,
});
5

Verify Installation

Create a test page to verify Sentry is working:
<!-- pages/sentry-test.vue -->
<template>
  <button @click="triggerError">
    Trigger Test Error
  </button>
</template>

<script setup>
import * as Sentry from '@sentry/nuxt';

function triggerError() {
  Sentry.captureException(new Error('Test error'));
}
</script>
Visit the page and click the button. Check your Sentry dashboard to see the error.

Configuration Options

Configure Sentry in your nuxt.config.ts:
export default defineNuxtConfig({
  modules: ['@sentry/nuxt/module'],
  
  sentry: {
    // Sentry DSN
    dsn: process.env.SENTRY_DSN,
    
    // Enable source maps upload
    sourceMapsUploadOptions: {
      org: 'your-org',
      project: 'your-project',
      authToken: process.env.SENTRY_AUTH_TOKEN,
    },
    
    // Enable debugging in development
    debug: process.env.NODE_ENV === 'development',
  },
});

Error Handling

Automatic Error Capture

The SDK automatically captures:
  • Unhandled exceptions on client and server
  • Vue errors and warnings
  • API errors
  • Server middleware errors

Manual Error Capture

In Vue components:
<template>
  <div>
    <button @click="fetchData">Load Data</button>
  </div>
</template>

<script setup>
import * as Sentry from '@sentry/nuxt';

const fetchData = async () => {
  try {
    const data = await $fetch('/api/data');
    return data;
  } catch (error) {
    Sentry.captureException(error);
    throw error;
  }
};
</script>

In Server API Routes

// server/api/users.ts
import * as Sentry from '@sentry/nuxt';

export default defineEventHandler(async (event) => {
  try {
    const users = await prisma.user.findMany();
    return users;
  } catch (error) {
    Sentry.captureException(error);
    throw createError({
      statusCode: 500,
      message: 'Failed to fetch users',
    });
  }
});

In Server Middleware

// server/middleware/auth.ts
import * as Sentry from '@sentry/nuxt';

export default defineEventHandler((event) => {
  try {
    const token = getCookie(event, 'auth_token');
    
    if (!token) {
      throw new Error('No auth token');
    }
    
    // Verify token
    const user = verifyToken(token);
    event.context.user = user;
  } catch (error) {
    Sentry.captureException(error);
    throw createError({
      statusCode: 401,
      message: 'Unauthorized',
    });
  }
});

Performance Monitoring

Automatic Instrumentation

The SDK automatically creates spans for:
  • Page loads and navigation
  • API requests
  • Server routes
  • Database queries (with integrations)

Custom Spans

In components:
<script setup>
import * as Sentry from '@sentry/nuxt';

const loadData = async () => {
  const data = await Sentry.startSpan(
    { name: 'fetch-user-data', op: 'http.client' },
    async () => {
      return await $fetch('/api/users');
    }
  );
  
  return data;
};
</script>
In server routes:
// server/api/products.ts
import * as Sentry from '@sentry/nuxt';

export default defineEventHandler(async (event) => {
  const products = await Sentry.startSpan(
    { name: 'fetch-products', op: 'db.query' },
    async () => {
      return await prisma.product.findMany();
    }
  );
  
  return products;
});

Setting Context

User Context

// composables/useAuth.ts
import * as Sentry from '@sentry/nuxt';

export function useAuth() {
  const user = useState('user');
  
  watch(user, (newUser) => {
    if (newUser) {
      Sentry.setUser({
        id: newUser.id,
        email: newUser.email,
        username: newUser.username,
      });
    } else {
      Sentry.setUser(null);
    }
  }, { immediate: true });
  
  return { user };
}

Tags and Extra Context

import * as Sentry from '@sentry/nuxt';

// Set tags
Sentry.setTag('locale', useRoute().params.locale);
Sentry.setTag('user_tier', 'premium');

// Set extra context
Sentry.setExtra('api_version', 'v2');
Sentry.setContext('app', {
  name: 'My App',
  version: '1.0.0',
});
import * as Sentry from '@sentry/nuxt';

Sentry.addBreadcrumb({
  category: 'navigation',
  message: 'User navigated to products page',
  level: 'info',
  data: {
    from: previousRoute.path,
    to: currentRoute.path,
  },
});

Composables

useSentry Composable

Create a custom composable for easier Sentry usage:
// composables/useSentry.ts
import * as Sentry from '@sentry/nuxt';

export function useSentry() {
  const captureError = (error: Error, context?: Record<string, any>) => {
    if (context) {
      Sentry.withScope((scope) => {
        Object.entries(context).forEach(([key, value]) => {
          scope.setContext(key, value);
        });
        Sentry.captureException(error);
      });
    } else {
      Sentry.captureException(error);
    }
  };
  
  const captureMessage = (message: string, level: Sentry.SeverityLevel = 'info') => {
    Sentry.captureMessage(message, level);
  };
  
  const addBreadcrumb = (breadcrumb: Sentry.Breadcrumb) => {
    Sentry.addBreadcrumb(breadcrumb);
  };
  
  return {
    captureError,
    captureMessage,
    addBreadcrumb,
  };
}
Use it in components:
<script setup>
const { captureError, addBreadcrumb } = useSentry();

const submitForm = async () => {
  addBreadcrumb({
    category: 'form',
    message: 'User submitted contact form',
  });
  
  try {
    await $fetch('/api/contact', {
      method: 'POST',
      body: formData,
    });
  } catch (error) {
    captureError(error, {
      form: 'contact',
      data: formData,
    });
  }
};
</script>

Session Replay

Configure Session Replay in your client config:
// sentry.client.config.ts
import * as Sentry from '@sentry/nuxt';

Sentry.init({
  dsn: 'YOUR_DSN_HERE',
  
  integrations: [
    Sentry.replayIntegration({
      maskAllText: true,
      blockAllMedia: true,
      maskAllInputs: true,
    }),
  ],
  
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
});

Pinia Integration

Track Pinia store actions:
// stores/user.ts
import { defineStore } from 'pinia';
import * as Sentry from '@sentry/nuxt';

export const useUserStore = defineStore('user', () => {
  const user = ref(null);
  
  const fetchUser = async () => {
    Sentry.addBreadcrumb({
      category: 'store',
      message: 'Fetching user data',
    });
    
    try {
      const data = await $fetch('/api/user');
      user.value = data;
    } catch (error) {
      Sentry.captureException(error);
      throw error;
    }
  };
  
  return {
    user,
    fetchUser,
  };
});

Source Maps

Source maps are automatically uploaded when configured in nuxt.config.ts:
export default defineNuxtConfig({
  modules: ['@sentry/nuxt/module'],
  
  sentry: {
    sourceMapsUploadOptions: {
      org: 'your-org',
      project: 'your-project',
      authToken: process.env.SENTRY_AUTH_TOKEN,
      
      // Upload only in production
      enabled: process.env.NODE_ENV === 'production',
      
      // Clean up artifacts after upload
      cleanArtifacts: true,
    },
  },
});

Advanced Configuration

Environment Detection

// sentry.client.config.ts
import * as Sentry from '@sentry/nuxt';

Sentry.init({
  dsn: 'YOUR_DSN_HERE',
  environment: process.env.NODE_ENV,
  enabled: process.env.NODE_ENV === 'production',
});

Sampling

Sentry.init({
  dsn: 'YOUR_DSN_HERE',
  
  tracesSampler: (samplingContext) => {
    // Don't sample health checks
    if (samplingContext.request?.url?.includes('/health')) {
      return 0;
    }
    
    // Sample API routes at 50%
    if (samplingContext.request?.url?.startsWith('/api')) {
      return 0.5;
    }
    
    return 0.1;
  },
});

Filtering Events

Sentry.init({
  dsn: 'YOUR_DSN_HERE',
  
  beforeSend(event, hint) {
    // Don't send errors from development
    if (process.env.NODE_ENV === 'development') {
      return null;
    }
    
    return event;
  },
});

Runtime Configuration

Use runtime config for dynamic DSN:
// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      sentryDsn: process.env.SENTRY_DSN,
    },
  },
});
Then in your Sentry config:
// sentry.client.config.ts
import * as Sentry from '@sentry/nuxt';

const config = useRuntimeConfig();

Sentry.init({
  dsn: config.public.sentryDsn,
  // ... other options
});

Troubleshooting

Errors Not Captured

  1. Ensure the Sentry module is registered in nuxt.config.ts
  2. Check that both sentry.client.config.ts and sentry.server.config.ts exist
  3. Verify DSN is correct in both configs

Source Maps Not Working

  1. Check SENTRY_AUTH_TOKEN is set correctly
  2. Verify org and project match your Sentry organization
  3. Ensure sourceMapsUploadOptions is configured

Performance Data Missing

  1. Ensure tracesSampleRate is greater than 0
  2. Check that Sentry module is loaded before your app
  3. Verify Sentry is initialized in both client and server configs
Make sure to create both sentry.client.config.ts and sentry.server.config.ts in your project root, not in a subdirectory.

Module Not Loading

If the Sentry module isn’t loading:
  1. Update to the latest @sentry/nuxt version
  2. Clear .nuxt directory: rm -rf .nuxt
  3. Reinstall dependencies
  4. Check Nuxt version compatibility

Next Steps

Build docs developers (and LLMs) love