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.
Integration method
Amplitude's browser SDK (@amplitude/analytics-browser) is a pure JavaScript package that works natively in Bolt's WebContainer. Initialize it with your API key, then call track() and identify() from any client component. For server-side event tracking (backend events like payment processing), use Amplitude's HTTP API v2 via a Next.js API route with your secret key. The browser SDK is the primary integration path for most Bolt apps.
Prerequisites
- 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
Create an Amplitude Project and Get Your API Key
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.
Install Amplitude analytics. Add @amplitude/analytics-browser to my project. Create lib/analytics.ts that initializes Amplitude with import.meta.env.VITE_AMPLITUDE_API_KEY and exports track(event, properties) and identify(userId, userProperties) wrapper functions.
Paste this in Bolt.new chat
1// lib/analytics.ts2import * as amplitude from '@amplitude/analytics-browser';34let initialized = false;56export function initAmplitude() {7 const apiKey = import.meta.env.VITE_AMPLITUDE_API_KEY;8 if (!apiKey || initialized) return;910 amplitude.init(apiKey, undefined, {11 defaultTracking: {12 pageViews: true, // auto-track page views13 sessions: true, // auto-track session start/end14 formInteractions: false, // disable noisy form field tracking15 fileDownloads: false,16 },17 logLevel: import.meta.env.DEV18 ? amplitude.Types.LogLevel.Debug19 : amplitude.Types.LogLevel.None,20 });2122 initialized = true;23}2425export function track(26 eventName: string,27 properties?: Record<string, unknown>28) {29 amplitude.track(eventName, properties);30}3132export function identify(33 userId: string,34 userProperties?: Record<string, unknown>35) {36 amplitude.setUserId(userId);3738 if (userProperties) {39 const identifyEvent = new amplitude.Identify();40 Object.entries(userProperties).forEach(([key, value]) => {41 identifyEvent.set(key, value as amplitude.Types.ValidPropertyType);42 });43 amplitude.identify(identifyEvent);44 }45}4647export function reset() {48 amplitude.reset(); // clears userId and deviceId on logout49}Pro tip: The defaultTracking.pageViews: true option automatically tracks page views as 'Page Viewed' events with the URL and page title — you get navigation analytics without writing any additional code. Disable formInteractions to avoid tracking sensitive form field data inadvertently.
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.
Initialize Amplitude and Track Your First Events
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.
Initialize Amplitude in my app's root component and add event tracking to the most important user interactions. Call initAmplitude() in App.tsx or layout.tsx. Add track() calls to: the main CTA button ('cta_clicked' with button_text property), the dashboard page load ('dashboard_viewed' with section property), and any data submission forms ('form_submitted' with form_name property).
Paste this in Bolt.new chat
1// main.tsx (Vite) or app/layout.tsx (Next.js)2// Vite: main.tsx3import React from 'react';4import ReactDOM from 'react-dom/client';5import App from './App';6import { initAmplitude } from './lib/analytics';7import './index.css';89initAmplitude(); // Initialize before mounting1011ReactDOM.createRoot(document.getElementById('root')!).render(12 <React.StrictMode>13 <App />14 </React.StrictMode>15);1617// Example component with event tracking:18// components/Dashboard.tsx19import { useEffect } from 'react';20import { track } from '@/lib/analytics';2122export function Dashboard() {23 useEffect(() => {24 track('dashboard_viewed', {25 timestamp: new Date().toISOString(),26 });27 }, []);2829 const handleGenerateReport = (reportType: string) => {30 track('report_generated', {31 report_type: reportType,32 generated_at: new Date().toISOString(),33 });34 // actual report generation logic...35 };3637 return (38 <div>39 <h1>Dashboard</h1>40 <button onClick={() => handleGenerateReport('monthly')}>41 Generate Monthly Report42 </button>43 </div>44 );45}Pro tip: Open Amplitude's Event Explorer (Data → Event Explorer) while testing in Bolt's preview to see events arrive in real time. This makes it easy to verify event names, property shapes, and that tracking fires at the right moments during development.
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.
Add User Identification for Segmented Analytics
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.
Add user identification to my Amplitude integration. After successful login/signup, call identify() with the user's ID and these properties: email, plan (free/pro/enterprise), created_at, and company_name if available. On logout, call reset() to clear the user ID. Import identify and reset from lib/analytics.ts.
Paste this in Bolt.new chat
1// hooks/useAmplitudeIdentify.ts2import { useEffect } from 'react';3import { identify, reset } from '@/lib/analytics';45interface UserProfile {6 id: string;7 email: string;8 plan: 'free' | 'pro' | 'enterprise';9 createdAt: string;10 companyName?: string;11}1213export function useAmplitudeIdentify(user: UserProfile | null) {14 useEffect(() => {15 if (user) {16 identify(user.id, {17 email: user.email,18 plan: user.plan,19 created_at: user.createdAt,20 company_name: user.companyName ?? '',21 });22 } else {23 reset(); // Clear identity on logout24 }25 }, [user?.id, user?.plan]); // Re-identify if plan changes26}2728// Usage in your root authenticated component:29// const { user } = useAuth();30// useAmplitudeIdentify(user);Pro tip: Don't set userId to a user-facing value like email alone — use an internal ID that won't change. Email can change (users update accounts), but internal user IDs are stable. Store the user ID as a UUID in your database and use that as the Amplitude userId.
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.
Add Server-Side Tracking for Critical Business Events
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.
Create a utility at lib/amplitude-server.ts that exports a trackServerEvent(eventType, userId, properties) function using Amplitude HTTP API v2. Use AMPLITUDE_SECRET_KEY from process.env. Then call trackServerEvent('payment_completed', userId, { plan, amount, currency }) in my Stripe webhook handler after a successful checkout.
Paste this in Bolt.new chat
1// lib/amplitude-server.ts2const AMPLITUDE_HTTP_API = 'https://api2.amplitude.com/2/httpapi';34export async function trackServerEvent(5 eventType: string,6 userId: string,7 properties?: Record<string, unknown>8): Promise<void> {9 const apiKey = process.env.AMPLITUDE_API_KEY;10 if (!apiKey) {11 console.warn('AMPLITUDE_API_KEY not configured — skipping server event');12 return;13 }1415 try {16 await fetch(AMPLITUDE_HTTP_API, {17 method: 'POST',18 headers: { 'Content-Type': 'application/json' },19 body: JSON.stringify({20 api_key: apiKey,21 events: [22 {23 event_type: eventType,24 user_id: userId,25 time: Date.now(),26 event_properties: properties ?? {},27 insert_id: `${userId}-${eventType}-${Date.now()}`, // dedup key28 },29 ],30 }),31 });32 } catch (error) {33 // Non-blocking — analytics failure shouldn't break core flows34 console.error('Amplitude server tracking failed:', error);35 }36}3738// Usage in Stripe webhook route:39// await trackServerEvent('payment_completed', userId, {40// plan: 'pro',41// amount: 2900,42// currency: 'usd',43// });Pro tip: The insert_id field provides deduplication — if the same request is retried (webhook retry, network error), Amplitude ignores duplicate events with the same insert_id. Always set a meaningful insert_id for payment and subscription events to prevent double-counting in revenue analytics.
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.
Common 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.
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.
Copy this prompt to try it in Bolt.new
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.
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.
Copy this prompt to try it in Bolt.new
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.
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.
Copy this prompt to try it in Bolt.new
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.
1// Verify initialization in browser console:2import * as amplitude from '@amplitude/analytics-browser';3console.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.
1// Correct package for browser/Bolt use:2// npm install @amplitude/analytics-browser3// 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.
1// Call identify whenever user is available, not just on login2useEffect(() => {3 if (user) {4 identify(user.id, { email: user.email, plan: user.plan });5 }6}, [user]); // runs when user loads from session storageBest 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
Alternatives
Mixpanel and Amplitude have very similar feature sets for product analytics; Mixpanel has a larger free tier (20M events/month) while Amplitude has stronger cohort analysis and retention tools.
Google Analytics is free and covers web traffic analytics well, but Amplitude is purpose-built for product analytics with better funnel and retention analysis for SaaS products.
Segment is a customer data platform that routes events to multiple destinations including Amplitude, useful when you want to send the same events to analytics, CRM, and marketing tools simultaneously.
FullStory captures session recordings and auto-captures interactions for qualitative analysis, complementing Amplitude's quantitative event data for UX investigation.
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.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation