# How to Integrate Bolt.new with Amplitude

- Tool: Bolt.new
- Difficulty: Intermediate
- Time required: 20 minutes
- Last updated: April 2026

## TL;DR

Integrate Amplitude with Bolt.new by installing the @amplitude/analytics-browser SDK — it works natively in Bolt's WebContainer. Initialize with your API key, track events, and identify users entirely from the browser. For server-side event tracking or exporting analytics data, use Amplitude's HTTP API via a Next.js API route. The free Starter plan includes 10 million events per month.

## Add Product Analytics to Your Bolt.new App with Amplitude

Amplitude is one of the two leading product analytics platforms (alongside Mixpanel), known for its powerful funnel analysis, retention charts, and behavioral cohorts. Its Starter plan is exceptionally generous at 10 million events per month for free — far more than most Bolt apps will need. For context, a 1,000-user app with each user triggering 100 events per month uses 100,000 events, well within Amplitude's free tier. This makes Amplitude one of the best zero-cost analytics options for Bolt-built products in early stages.

Amplitude's browser SDK is a pure JavaScript package that installs and runs perfectly in Bolt's WebContainer runtime. Unlike database drivers that require TCP connections, the SDK sends events via HTTPS to Amplitude's servers — fully compatible with WebContainers' HTTP-only networking. You can initialize Amplitude, start tracking events, and see data in the Amplitude dashboard all from the Bolt preview environment without deploying first. This makes iteration fast: prompt Bolt to add event tracking, test in the preview, and see events arrive in real time in Amplitude's debug view.

The integration pattern follows a separation of concerns: client-side events (button clicks, page views, form submissions, feature interactions) are tracked directly with the browser SDK from React components. Server-side events (subscription created, payment processed, webhook received) are tracked via Amplitude's HTTP API v2 from Next.js API routes. This separation ensures event tracking is reliable — client-side code might be blocked by ad blockers, while server-side events always reach Amplitude. For most Bolt apps, the browser SDK alone is sufficient to get started.

## Before you start

- An Amplitude account at amplitude.com (free Starter plan available — no credit card required)
- Your Amplitude API key from Settings → Projects → [Your Project] → General
- A Bolt.new project (Vite default works with the browser SDK; Next.js needed for server-side tracking)
- Basic understanding of event tracking concepts (events, properties, user identity)
- A deployed Netlify or Bolt Cloud URL if you need to track events from server-side webhooks

## Step-by-step guide

### 1. Create an Amplitude Project and Get Your API Key

Sign up at amplitude.com — the Starter plan is free and doesn't require a credit card. After signing up, Amplitude creates a default project for you. Go to Settings (gear icon in top right) → Projects → click your project name → General tab. Copy the API Key — this is a public identifier safe to include in client-side code. Amplitude also provides a Secret Key for server-side use — copy that too if you plan to track server-side events, and store it securely. Amplitude's data model is straightforward: events are named actions (strings like 'button_clicked') with optional properties (objects with metadata like { button_name: 'sign_up' }). Users are identified by a userId (set when users log in) or a deviceId (auto-generated by the SDK for anonymous users). User properties (profile data like email, plan, signup_date) are set via the identify() call and persist across events. The Amplitude dashboard has a real-time debugger: go to Govern → Event Explorer or open any chart and search for your event name. New events appear within seconds of being sent, making it easy to verify tracking works during development in Bolt's preview.

```
// lib/analytics.ts
import * as amplitude from '@amplitude/analytics-browser';

let initialized = false;

export function initAmplitude() {
  const apiKey = import.meta.env.VITE_AMPLITUDE_API_KEY;
  if (!apiKey || initialized) return;

  amplitude.init(apiKey, undefined, {
    defaultTracking: {
      pageViews: true,      // auto-track page views
      sessions: true,        // auto-track session start/end
      formInteractions: false, // disable noisy form field tracking
      fileDownloads: false,
    },
    logLevel: import.meta.env.DEV
      ? amplitude.Types.LogLevel.Debug
      : amplitude.Types.LogLevel.None,
  });

  initialized = true;
}

export function track(
  eventName: string,
  properties?: Record<string, unknown>
) {
  amplitude.track(eventName, properties);
}

export function identify(
  userId: string,
  userProperties?: Record<string, unknown>
) {
  amplitude.setUserId(userId);

  if (userProperties) {
    const identifyEvent = new amplitude.Identify();
    Object.entries(userProperties).forEach(([key, value]) => {
      identifyEvent.set(key, value as amplitude.Types.ValidPropertyType);
    });
    amplitude.identify(identifyEvent);
  }
}

export function reset() {
  amplitude.reset(); // clears userId and deviceId on logout
}
```

**Expected result:** The Amplitude SDK is initialized. initAmplitude() can be called from the app root, and track() can be called from any component. Events show up in Amplitude's Event Explorer within seconds.

### 2. Initialize Amplitude and Track Your First Events

Initialize Amplitude in the root component of your app so it's ready before any events are tracked. In a Vite React app (Bolt's default), this goes in main.tsx or App.tsx. In a Next.js app, use the root layout.tsx. Call initAmplitude() once — the initialized guard in the utility prevents double initialization during React strict mode's double-invoke. Then add event tracking to meaningful user interactions: button clicks, feature usage, form submissions. The event name should be a short, descriptive string in snake_case — standard convention in product analytics is verb + noun format ('post_created', 'dashboard_viewed', 'filter_applied'). Properties enrich events with context: instead of just tracking 'button_clicked', track 'button_clicked' with { button_id: 'upgrade_cta', page: '/pricing', user_plan: 'free' }. Properties are what make analytics useful — without them, you know something happened but not why or how. Avoid tracking sensitive user data in event properties (passwords, full credit card numbers, full addresses) — Amplitude is a third-party service and these would constitute a data breach.

```
// main.tsx (Vite) or app/layout.tsx (Next.js)
// Vite: main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { initAmplitude } from './lib/analytics';
import './index.css';

initAmplitude(); // Initialize before mounting

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// Example component with event tracking:
// components/Dashboard.tsx
import { useEffect } from 'react';
import { track } from '@/lib/analytics';

export function Dashboard() {
  useEffect(() => {
    track('dashboard_viewed', {
      timestamp: new Date().toISOString(),
    });
  }, []);

  const handleGenerateReport = (reportType: string) => {
    track('report_generated', {
      report_type: reportType,
      generated_at: new Date().toISOString(),
    });
    // actual report generation logic...
  };

  return (
    <div>
      <h1>Dashboard</h1>
      <button onClick={() => handleGenerateReport('monthly')}>
        Generate Monthly Report
      </button>
    </div>
  );
}
```

**Expected result:** Events start flowing to Amplitude immediately after initialization. The Amplitude Event Explorer shows new events within 5-10 seconds of user actions. Page views are tracked automatically for every navigation.

### 3. Add User Identification for Segmented Analytics

Anonymous event tracking is a useful start, but Amplitude's real power comes from user-level analytics: retention by cohort, feature adoption by plan tier, churn correlation with behavior patterns. These require identifying users after they log in. The `identify()` function in the utility sets a userId (typically your database user ID or email) and user properties (plan, signup_date, company, role). Set userId immediately after successful login and clear it with `reset()` on logout. User properties should capture attributes that you'll want to segment analysis by: pricing tier, acquisition source, key feature adoption milestones. Amplitude stores user properties persistently — once set, they're associated with all future events from that user. When a user upgrades their plan, update the user property with a new identify() call — Amplitude timestamps property changes and allows you to analyze behavior before and after. One important privacy consideration: only set user properties you have explicit permission to collect under your privacy policy. For GDPR/CCPA compliance, Amplitude provides opt-out APIs.

```
// hooks/useAmplitudeIdentify.ts
import { useEffect } from 'react';
import { identify, reset } from '@/lib/analytics';

interface UserProfile {
  id: string;
  email: string;
  plan: 'free' | 'pro' | 'enterprise';
  createdAt: string;
  companyName?: string;
}

export function useAmplitudeIdentify(user: UserProfile | null) {
  useEffect(() => {
    if (user) {
      identify(user.id, {
        email: user.email,
        plan: user.plan,
        created_at: user.createdAt,
        company_name: user.companyName ?? '',
      });
    } else {
      reset(); // Clear identity on logout
    }
  }, [user?.id, user?.plan]); // Re-identify if plan changes
}

// Usage in your root authenticated component:
// const { user } = useAuth();
// useAmplitudeIdentify(user);
```

**Expected result:** After login, Amplitude associates all events with the identified user ID. The Amplitude Users chart shows individual user paths. Cohort analysis segmented by 'plan' property becomes possible.

### 4. Add Server-Side Tracking for Critical Business Events

Some events must be tracked server-side to guarantee they reach Amplitude even if users have ad blockers, VPNs, or network issues that interfere with client-side SDK calls. Payment completions, subscription changes, webhook-triggered actions, and audit-critical events should always be tracked server-side from Next.js API routes using Amplitude's HTTP API v2. The HTTP API v2 endpoint is `https://api2.amplitude.com/2/httpapi` and accepts a POST request with an api_key and events array. Each event object specifies the event_type, user_id, and optional event_properties. This approach ensures 100% reliability for your most important business events regardless of client-side tracking failures. Store your Amplitude Secret Key (different from the API Key) in the AMPLITUDE_SECRET_KEY environment variable — the secret key is required for server-side HTTP API calls and must never be in client-side code. The secret key can be found in Amplitude Settings → Projects → your project → General → Secret Key.

```
// lib/amplitude-server.ts
const AMPLITUDE_HTTP_API = 'https://api2.amplitude.com/2/httpapi';

export async function trackServerEvent(
  eventType: string,
  userId: string,
  properties?: Record<string, unknown>
): Promise<void> {
  const apiKey = process.env.AMPLITUDE_API_KEY;
  if (!apiKey) {
    console.warn('AMPLITUDE_API_KEY not configured — skipping server event');
    return;
  }

  try {
    await fetch(AMPLITUDE_HTTP_API, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        api_key: apiKey,
        events: [
          {
            event_type: eventType,
            user_id: userId,
            time: Date.now(),
            event_properties: properties ?? {},
            insert_id: `${userId}-${eventType}-${Date.now()}`, // dedup key
          },
        ],
      }),
    });
  } catch (error) {
    // Non-blocking — analytics failure shouldn't break core flows
    console.error('Amplitude server tracking failed:', error);
  }
}

// Usage in Stripe webhook route:
// await trackServerEvent('payment_completed', userId, {
//   plan: 'pro',
//   amount: 2900,
//   currency: 'usd',
// });
```

**Expected result:** Payment and subscription events tracked server-side appear in Amplitude alongside client-side events. These events are not affected by ad blockers or client-side failures. Revenue charts in Amplitude reflect actual payment events.

## Best practices

- Use snake_case for event names and properties to maintain consistency across your analytics schema (e.g., 'feature_enabled' not 'featureEnabled')
- Initialize Amplitude as early as possible in the app lifecycle — before mounting React, so automatic page view tracking captures the initial page
- Track 'what happened' in event names and 'context' in properties — 'button_clicked' with { button_id, page } is more useful than creating dozens of button-specific event types
- Call reset() on logout to clear the userId — otherwise the next user on the same device would be associated with the previous user's identity
- Use server-side HTTP API tracking for payment, subscription, and other business-critical events that must not be blocked by ad blockers
- Set the insert_id field in server-side events for idempotency — prevents double-counting if webhooks are retried
- Respect user privacy — only collect events and properties covered by your privacy policy, and implement the Amplitude opt-out API for GDPR/CCPA compliance

## Use cases

### Feature Adoption Tracking

Track which features users actually use versus which they ignore. Add event tracking to key feature interactions — button clicks, form submissions, feature views — to build Amplitude funnels showing where users drop off in multi-step workflows. Product teams use this data to prioritize improvements.

Prompt example:

```
Add Amplitude analytics to my Bolt app. Initialize Amplitude in my main layout with my API key from VITE_AMPLITUDE_API_KEY. Track these events: 'dashboard_viewed' when the dashboard page loads, 'report_generated' with a type property when a user generates a report, 'settings_saved' when settings are saved. Import amplitude from @amplitude/analytics-browser.
```

### User Onboarding Funnel

Track completion rates through a multi-step onboarding flow to identify where new users abandon the process. Events for each step (step_1_completed, step_2_completed, profile_setup_skipped) feed into Amplitude's funnel analysis to show where the biggest drop-offs occur.

Prompt example:

```
Add onboarding funnel tracking using Amplitude. Track events at each step of my onboarding flow: 'onboarding_started' on step 1, 'account_details_completed' on step 2, 'preferences_set' on step 3 with a preferences object, 'onboarding_completed' on the final step with a total_time_seconds property. Also call identify() with the user's email and plan when they complete signup.
```

### Revenue Analytics Dashboard

Track payment and subscription events server-side from Next.js API routes so they can't be blocked by ad blockers. Send 'subscription_started', 'payment_completed', and 'subscription_cancelled' events with revenue amounts and plan types to Amplitude's HTTP API for accurate revenue analytics.

Prompt example:

```
Add server-side Amplitude tracking to my payment flow. In my /api/stripe/webhook route, after processing a successful checkout.session.completed event, send a 'payment_completed' event to Amplitude's HTTP API v2 with userId, revenue, and plan_type. Use AMPLITUDE_SECRET_KEY for server-side calls. This ensures payment events reach Amplitude even if the user has an ad blocker.
```

## Troubleshooting

### Events don't appear in Amplitude Event Explorer after tracking

Cause: The VITE_AMPLITUDE_API_KEY environment variable is not set, the API key is incorrect, or initAmplitude() was not called before the first track() call.

Solution: Check that .env has VITE_AMPLITUDE_API_KEY set (not AMPLITUDE_API_KEY — Vite requires the VITE_ prefix). Verify the key in Amplitude Settings → Projects → General matches exactly. Check the browser console for Amplitude initialization errors — in development, the SDK logs at Debug level.

```
// Verify initialization in browser console:
import * as amplitude from '@amplitude/analytics-browser';
console.log('Amplitude initialized:', amplitude.getSessionId() !== undefined);
```

### Amplitude SDK fails to install with 'Cannot install native module' error

Cause: This shouldn't happen with @amplitude/analytics-browser — it's pure JavaScript. If you see this error, you may have accidentally installed @amplitude/analytics-node (the server SDK) instead of the browser SDK.

Solution: Verify you installed @amplitude/analytics-browser, not @amplitude/analytics-node. The browser SDK is pure JavaScript and works in Bolt's WebContainer without any native module compilation.

```
// Correct package for browser/Bolt use:
// npm install @amplitude/analytics-browser
// NOT: npm install @amplitude/analytics-node (requires Node.js, not WebContainer)
```

### User identity is not persisted after page refresh — events come from different anonymous users

Cause: The identify() call is only made after login, but if the user was already logged in from a previous session, identify() is not called on the current session.

Solution: Call identify() whenever the auth state loads, not just on login events. If the user is already logged in when the app loads, identify() should still be called to associate the current Amplitude deviceId session with the userId.

```
// Call identify whenever user is available, not just on login
useEffect(() => {
  if (user) {
    identify(user.id, { email: user.email, plan: user.plan });
  }
}, [user]); // runs when user loads from session storage
```

## Frequently asked questions

### Does the Amplitude browser SDK work in Bolt's WebContainer?

Yes. The @amplitude/analytics-browser SDK is pure JavaScript with no native module dependencies. It sends events via HTTPS to Amplitude's servers, which is fully supported in Bolt's WebContainer runtime. You can initialize Amplitude, track events, and see them appear in Amplitude's Event Explorer all from the Bolt preview without deploying.

### How many events can I track for free with Amplitude?

Amplitude's Starter plan includes 10 million events per month at no cost with no credit card required. For context, a 1,000 monthly active user app where each user triggers 100 events uses 100,000 events — just 1% of the free allocation. Most early-stage Bolt apps won't exceed the free tier for months or years.

### Should I use client-side or server-side event tracking?

Use the browser SDK (@amplitude/analytics-browser) for most events — page views, feature interactions, button clicks. Use the server-side HTTP API for critical business events like payments, subscriptions, and webhook-triggered actions where guaranteed delivery matters. Client-side events may be blocked by ad blockers (roughly 30% of tech-savvy users); server-side events always reach Amplitude.

### What's the difference between Amplitude API Key and Secret Key?

The API Key is a project identifier safe for client-side code — include it in VITE_AMPLITUDE_API_KEY. The Secret Key is a sensitive credential for server-side HTTP API calls — store it in AMPLITUDE_SECRET_KEY and never expose it in browser code. Both are found in Amplitude Settings → Projects → General. If exposed, regenerate immediately from the same location.

### How do I verify Amplitude is working in Bolt's preview?

Open Amplitude's Event Explorer (Data → Event Explorer in the Amplitude dashboard) while your Bolt preview is open. Interact with tracked features in the preview — events should appear in the Explorer within 5-10 seconds. Enable Debug level logging by setting logLevel: amplitude.Types.LogLevel.Debug in the init options to see event sends in the browser console.

---

Source: https://www.rapidevelopers.com/bolt-ai-integrations/amplitude
© RapidDev — https://www.rapidevelopers.com/bolt-ai-integrations/amplitude
