Get started with Crashlytics for Web

Select platform: iOS+ Android Android NDK Web Flutter Unity


This guide describes how to get started with Firebase Crashlytics in your web app.

After you've set up the Firebase Crashlytics SDK in your app, you can get comprehensive crash reports in the Firebase console. With Crashlytics for web apps, you get reports for errors.

Before you begin

Setting up Crashlytics requires tasks both in the Firebase console and your IDE (like adding your app's Firebase configuration and the Crashlytics SDK). To finish setup, you'll need to force a test crash to send your first crash report to Firebase.

To manually set up Crashlytics in your web app, make sure you have completed the following prerequisites:

  • Create a Firebase project and Firebase app if you don't already have one. If you haven't already, add Firebase to your JavaScript project.

  • Make sure that your account has Owner permissions on your project. This is required to enable the necessary APIs and IAM roles.

  • Make sure that your Firebase project is on the pay-as-you-go Blaze pricing plan. Crashlytics for web uses Cloud Logging for telemetry storage and Cloud Storage for source map storage, which are paid products with a no-cost tier. Learn more about Logging pricing and Cloud Storage pricing.

Step 1: Enable Crashlytics for your web app

Crashlytics for web uses Cloud Logging, Error Reporting, and Cloud Storage, so you need to enable these APIs and configure permissions for your project. You can enable Crashlytics for your web app using either the Firebase console or the Firebase CLI.

Use the Firebase console

  1. In the Firebase console, go to DevOps & Engagement > Crashlytics dashboard.

  2. Select your web app from the drop-down selector at the top of the page.

  3. Click Set up Crashlytics and follow the on-screen instructions.

Use the Firebase CLI

If you prefer configuring your project from the terminal or using an AI coding agent, you can use the Firebase CLI:

  1. Make sure that you have Firebase CLI v15.35.0 or later installed and that you're authenticated (firebase login). Learn how to install or update the Firebase CLI.

  2. Run the following command to set up Crashlytics for your web app:

    firebase crashlytics:setup \
      --app FIREBASE_APP_ID \
      --project PROJECT_ID
    

    This command performs the following setup steps:

    • Verifies that your project is on the pay-as-you-go Blaze pricing plan, and prompts you to upgrade if needed.

    • Enables the required Crashlytics and telemetry APIs (firebasetelemetry.googleapis.com, firebasetelemetryadmin.googleapis.com, firebasecrashlytics.googleapis.com, and clienttelemetry.googleapis.com).

    • If your web app's API key has API restrictions, adds clienttelemetry.googleapis.com to its allowed APIs.

    • Configures Crashlytics telemetry settings for your web app.

    • When run interactively, prompts you to optionally enable email alerts for new and regressed issues.

Step 2: Add and initialize the SDK in your app

  1. Install the Crashlytics SDK:

    npm install firebase
    
  2. Initialize your FirebaseApp instance:

    Create a central configuration utility file to use singleton initialization. To find your Firebase app configuration values, go to your Project settings > General page in the Firebase console, go to the Your apps card, and select your web app.

    // src/lib/firebase.ts
    import { initializeApp, getApps, getApp } from '@firebase/app';
    
    const firebaseConfig = {
      apiKey: "API_KEY",
      authDomain: "AUTH_DOMAIN",
      projectId: "PROJECT_ID",
      storageBucket: "STORAGE_BUCKET",
      messagingSenderId: "MESSAGING_SENDER_ID",
      appId: "FIREBASE_APP_ID"
    };
    
    // Guarantee singleton initialization across renders or module refreshes
    export const app = getApps().length === 0
      ? initializeApp(firebaseConfig)
      : getApp();
    

Step 3: Configure automatic error capturing for your framework

Both automatic framework error receivers and manual trackers use your shared FirebaseApp instance. Select your framework to configure automatic error capturing:

Angular

Integrate with the Angular global error-catching runtime and automatic route tracking by adding provideCrashlytics(() => app) to your app's providers in src/app/app.config.ts:

// src/app/app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideCrashlytics } from '@firebase/crashlytics/angular';
import { app } from '../lib/firebase'; // Shared initialization script
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideCrashlytics(() => app)
  ]
};

Next.js

Next.js 15.3+ (recommended): Client instrumentation (instrumentation-client.ts)

Next.js 15.3+ includes native client-side instrumentation via instrumentation-client.ts (or instrumentation-client.js). Next.js executes this file in the browser before React hydration begins.

Create src/instrumentation-client.ts (or instrumentation-client.ts in your project root if not using a src/ directory) and initialize Crashlytics:

// src/instrumentation-client.ts
import { getCrashlytics } from '@firebase/crashlytics';
import { app } from './lib/firebase'; // Shared initialization script

getCrashlytics(app);

This single file initializes Crashlytics before React hydration and automatically registers global error listeners (error and unhandledrejection) with zero modifications to src/app/layout.tsx or any React component.

Next.js < 15.3: Client-side (App Router layout)

For Next.js versions earlier than 15.3, layout.tsx is a Server Component by default. Because FirebaseApp is non-serializable, wrap <FirebaseCrashlytics> (from @firebase/crashlytics/react to initialize Crashlytics and capture uncaught errors) in a Client Component (such as src/components/CrashlyticsProvider.tsx) marked with the 'use client' directive:

// src/components/CrashlyticsProvider.tsx
'use client';

import React from 'react';
import { FirebaseCrashlytics } from '@firebase/crashlytics/react';
import { app } from '../lib/firebase'; // Shared initialization script

export function CrashlyticsProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <>
      <FirebaseCrashlytics firebaseApp={app} />
      {children}
    </>
  );
}

Then wrap your root layout with <CrashlyticsProvider>:

// src/app/layout.tsx
import React from 'react';
import { CrashlyticsProvider } from '../components/CrashlyticsProvider';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <CrashlyticsProvider>
          {children}
        </CrashlyticsProvider>
      </body>
    </html>
  );
}

React (without React Router)

Wrap your root app component (typically src/App.tsx or src/main.tsx) with the <FirebaseCrashlytics> error boundary component. This acts as the global receiver, handling unhandled rejections and exceptions from the browser and React UI. It wraps all child component hierarchies and automatically captures uncaught exceptions or routing errors:

// src/App.tsx
import React from 'react';
import { FirebaseCrashlytics } from '@firebase/crashlytics/react';
import { app } from './lib/firebase'; // Shared initialization script

export default function App({
  children,
}: {
  children?: React.ReactNode;
}) {
  return (
    <FirebaseCrashlytics firebaseApp={app}>
      {children}
    </FirebaseCrashlytics>
  );
}

React Router (v6+)

If you're using React Router v6+, replace React Router's <Routes> container with <CrashlyticsRoutes>. This automatically maps error boundaries across routes and tracks errors using templated path names, such as /profile/:userId:

// src/App.tsx
import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import { CrashlyticsRoutes } from '@firebase/crashlytics/react-router';
import { app } from './lib/firebase'; // Shared initialization script
import Home from './pages/Home';
import Profile from './pages/Profile';
import Product from './pages/Product';

export default function App() {
  return (
    <BrowserRouter>
      <CrashlyticsRoutes firebaseApp={app}>
        <Route path="/" element={<Home />} />
        <Route path="/profile/:userId" element={<Profile />} />
        <Route path="/product/:productId/details" element={<Product />} />
      </CrashlyticsRoutes>
    </BrowserRouter>
  );
}

TanStack Router

If your app uses TanStack Router, initialize Crashlytics with getCrashlytics(app) and attach default error recording directly inside your router instance configuration (defaultOnCatch):

import { recordError, getCrashlytics } from '@firebase/crashlytics';
import { app } from './lib/firebase'; // Shared initialization script

import { createRouter } from '@tanstack/react-router';
import { routeTree } from './routeTree.gen';

const crashlytics = getCrashlytics(app);

const router = createRouter({
  routeTree,
  defaultOnCatch: (error, errorInfo) => {
    recordError(crashlytics, error, errorInfo);
  },
});

(Optional) Step 4: Set up app versioning

Adding a clear version string to your web app builds is highly recommended so you can isolate regressions to specific deployments. Pass appVersion in CrashlyticsOptions when initializing the Crashlytics SDK for your framework (using a release string or a build-time environment variable, such as process.env.NEXT_PUBLIC_APP_VERSION or import.meta.env.VITE_APP_VERSION):

Angular

Pass a CrashlyticsOptions object with appVersion as the second argument to provideCrashlytics in src/app/app.config.ts:

// src/app/app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideCrashlytics } from '@firebase/crashlytics/angular';
import { app } from '../lib/firebase'; // Shared initialization script
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideCrashlytics(() => app, {
      appVersion: 'APP_VERSION'
    })
  ]
};

Next.js

Next.js 15.3+ (recommended): Client instrumentation (instrumentation-client.ts)

Pass a CrashlyticsOptions object with appVersion as the second argument to getCrashlytics in src/instrumentation-client.ts:

// src/instrumentation-client.ts
import { getCrashlytics } from '@firebase/crashlytics';
import { app } from './lib/firebase'; // Shared initialization script

getCrashlytics(app, {
  appVersion: 'APP_VERSION'
});

Next.js < 15.3: Client-side (App Router layout)

Pass crashlyticsOptions with appVersion to <FirebaseCrashlytics> in src/components/CrashlyticsProvider.tsx:

// src/components/CrashlyticsProvider.tsx
'use client';

import React from 'react';
import { FirebaseCrashlytics } from '@firebase/crashlytics/react';
import { app } from '../lib/firebase'; // Shared initialization script

const crashlyticsOptions = {
  appVersion: 'APP_VERSION'
};

export function CrashlyticsProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <>
      <FirebaseCrashlytics
        firebaseApp={app}
        crashlyticsOptions={crashlyticsOptions}
      />
      {children}
    </>
  );
}

React (without React Router)

Pass crashlyticsOptions with appVersion to <FirebaseCrashlytics> in src/App.tsx:

// src/App.tsx
import React from 'react';
import { FirebaseCrashlytics } from '@firebase/crashlytics/react';
import { app } from './lib/firebase'; // Shared initialization script

const crashlyticsOptions = {
  appVersion: 'APP_VERSION'
};

export default function App({
  children,
}: {
  children?: React.ReactNode;
}) {
  return (
    <FirebaseCrashlytics
      firebaseApp={app}
      crashlyticsOptions={crashlyticsOptions}
    >
      {children}
    </FirebaseCrashlytics>
  );
}

React Router (v6+)

Pass crashlyticsOptions with appVersion to <CrashlyticsRoutes> in src/App.tsx:

// src/App.tsx
import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import { CrashlyticsRoutes } from '@firebase/crashlytics/react-router';
import { app } from './lib/firebase'; // Shared initialization script
import Home from './pages/Home';
import Profile from './pages/Profile';
import Product from './pages/Product';

const crashlyticsOptions = {
  appVersion: 'APP_VERSION'
};

export default function App() {
  return (
    <BrowserRouter>
      <CrashlyticsRoutes
        firebaseApp={app}
        crashlyticsOptions={crashlyticsOptions}
      >
        <Route path="/" element={<Home />} />
        <Route path="/profile/:userId" element={<Profile />} />
        <Route path="/product/:productId/details" element={<Product />} />
      </CrashlyticsRoutes>
    </BrowserRouter>
  );
}

TanStack Router

Pass a CrashlyticsOptions object with appVersion as the second argument to getCrashlytics:

import { recordError, getCrashlytics } from '@firebase/crashlytics';
import { app } from './lib/firebase'; // Shared initialization script

import { createRouter } from '@tanstack/react-router';
import { routeTree } from './routeTree.gen';

const crashlytics = getCrashlytics(app, {
  appVersion: 'APP_VERSION'
});

const router = createRouter({
  routeTree,
  defaultOnCatch: (error, errorInfo) => {
    recordError(crashlytics, error, errorInfo);
  },
});

Step 5: Force a test crash

To finish setting up Crashlytics and see initial data in the Crashlytics dashboard of the Firebase console, you need to force a test crash.

  1. Add code to your app that you can use to force a test crash.

    Add a test button or route trigger to your React, Next.js, or Angular app that throws a runtime error when clicked:

    // Trigger an unhandled exception on button click or route load
    function handleTestCrash() {
      throw new Error("Crashlytics Web SDK Test Unhandled Error!");
    }
    

    If you configured automatic error capturing with <FirebaseCrashlytics> (React or Next.js), provideCrashlytics (Angular), or <CrashlyticsRoutes> (React Router), throwing this error automatically captures the exception and schedules it for upload.

  2. Build and run your app, then trigger the test error so that your app sends its first crash report to Firebase.

  3. In the Firebase console, go to the DevOps & Engagement > Crashlytics dashboard to check for your test crash report:

    1. Select your web app from the drop-down selector at the top of the page.

    2. Refresh the page. Your test exception should appear in the Issues table within a few minutes.

If you've refreshed the console and you're still not seeing the test crash after five to ten minutes, see Troubleshooting your setup.


Crashlytics is now monitoring your web app for errors. Visit the Crashlytics dashboard to view and investigate all your reports and statistics.

Next steps

  • Get readable crash reports: Set up automatic source map (.js.map) uploading so your production stack traces display original filenames and line numbers.
  • Customize crash reports: Learn how to report handled exceptions, add custom keys, force flush telemetry records, and configure sampling.