Amplitude Install / Embed Tag or SDK | OpsBlu Docs

Amplitude Install / Embed Tag or SDK

Deployment approach for installing Amplitude's tag or SDK across web, mobile, and server environments.

Overview

Amplitude is a product analytics platform that helps teams understand user behavior through event tracking and analysis. The Amplitude SDK ecosystem supports web, mobile, and server-side implementations with automatic session tracking, user identification, and attribution capture. This comprehensive guide covers all deployment methods to help you instrument Amplitude across your entire digital ecosystem.

Amplitude offers multiple SDKs optimized for different platforms: Browser SDK for web applications, iOS/Android SDKs for native mobile apps, and HTTP API for server-side tracking. Each SDK provides automatic event tracking capabilities alongside manual instrumentation for custom events.

Prerequisites

Before installing Amplitude, ensure you have:

  • Amplitude Account: Active account with appropriate plan (Free, Growth, or Enterprise)
  • API Key: Found in Settings > Projects > [Your Project] (format: 32-character alphanumeric string)
  • Project Selection: Separate projects for dev, staging, and production recommended
  • Data Taxonomy: Documented event names and property schemas (naming conventions)
  • User ID Strategy: Plan for how users will be identified (user_id vs device_id)
  • Consent Management: Cookie consent implementation if required by privacy regulations

Finding Your API Key

  1. Log into Amplitude at https://analytics.amplitude.com
  2. Navigate to Settings (gear icon) > Projects
  3. Select your project
  4. Copy the API Key from the project details
  5. For EU data residency, note the EU endpoint requirement

API Key Security: While Amplitude API keys are used client-side, avoid exposing them in public repositories. Use environment variables for different deployment environments.

Installation Methods

The npm package provides the best developer experience with TypeScript support and tree-shaking capabilities.

Installation

npm install @amplitude/analytics-browser
# or
yarn add @amplitude/analytics-browser
# or
pnpm add @amplitude/analytics-browser

Basic Implementation

// src/analytics/amplitude.js
import * as amplitude from '@amplitude/analytics-browser';

// Initialize Amplitude
amplitude.init('YOUR_API_KEY', {
  defaultTracking: {
    sessions: true,
    pageViews: true,
    formInteractions: false,
    fileDownloads: true
  },
  serverUrl: 'https://api2.amplitude.com/2/httpapi', // Use EU endpoint if required
  minIdLength: 5,
  partnerId: 'your-partner-id', // Optional
  sessionTimeout: 30 * 60 * 1000, // 30 minutes
  trackingOptions: {
    ipAddress: true,
    language: true,
    platform: true
  }
});

// Track page view
amplitude.track('Page Viewed', {
  page: window.location.pathname,
  title: document.title,
  referrer: document.referrer
});

export default amplitude;

Environment-Specific Configuration

// src/config/amplitude.config.js
const getAmplitudeConfig = () => {
  const environment = process.env.NODE_ENV;
  const apiKeys = {
    development: process.env.REACT_APP_AMPLITUDE_API_KEY_DEV,
    staging: process.env.REACT_APP_AMPLITUDE_API_KEY_STAGING,
    production: process.env.REACT_APP_AMPLITUDE_API_KEY_PROD
  };

  return {
    apiKey: apiKeys[environment],
    defaultTracking: {
      sessions: true,
      pageViews: true,
      formInteractions: environment === 'production',
      fileDownloads: true
    },
    logLevel: environment === 'production' ? amplitude.Types.LogLevel.Warn : amplitude.Types.LogLevel.Verbose,
    serverZone: 'US', // or 'EU'
    useBatch: true,
    flushIntervalMillis: 10000,
    flushQueueSize: 30
  };
};

export default getAmplitudeConfig;

Usage Example

import * as amplitude from '@amplitude/analytics-browser';
import getAmplitudeConfig from './config/amplitude.config';

// Initialize
const config = getAmplitudeConfig();
amplitude.init(config.apiKey, config);

// Track event
amplitude.track('Button Clicked', {
  buttonName: 'Sign Up',
  location: 'Header',
  timestamp: Date.now()
});

// Identify user
amplitude.setUserId('user-123');

// Set user properties
const identifyEvent = new amplitude.Identify();
identifyEvent.set('plan', 'premium');
identifyEvent.set('age', 25);
identifyEvent.add('loginCount', 1);
amplitude.identify(identifyEvent);

Method 2: Direct Script Tag (CDN)

For simpler implementations or non-bundled websites:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Your Website</title>

  <!-- Amplitude SDK -->
  <script type="text/javascript">
    !function(){"use strict";!function(e,t){var r=e.amplitude||{_q:[],_iq:{}};if(r.invoked)e.console&&console.error&&console.error("Amplitude snippet has been loaded.");else{r.invoked=!0;var n=t.createElement("script");n.type="text/javascript",n.integrity="sha384-x0ik2D45ZDEEEpYpEuDpmj05YY2jEvsdG+FLOw8LkJI4LI/Djj1+qMqAr/AqWXpS",n.crossOrigin="anonymous",n.async=!0,n.src="https://cdn.amplitude.com/libs/analytics-browser-2.0.1-min.js.gz",n.onload=function(){e.amplitude.runQueuedFunctions||console.log("[Amplitude] Error: could not load SDK")};var s=t.getElementsByTagName("script")[0];s.parentNode.insertBefore(n,s);for(var o=function(){return this._q=[],this},i=["add","append","clearAll","prepend","set","setOnce","unset","preInsert","postInsert","remove","getUserProperties"],a=0;a<i.length;a++)o.prototype[i[a]]=function(e){return function(){return this._q.push({name:e,args:Array.prototype.slice.call(arguments,0)}),this}}(i[a]);r.Identify=o;for(var c=function(){this._q=[];return this},u=["getEventProperties","setProductId","setQuantity","setPrice","setRevenue","setRevenueType","setEventProperties"],l=0;l<u.length;l++)c.prototype[u[l]]=function(e){return function(){return this._q.push({name:e,args:Array.prototype.slice.call(arguments,0)}),this}}(u[l]);r.Revenue=c;var p=["getDeviceId","setDeviceId","getSessionId","setSessionId","getUserId","setUserId","setOptOut","setTransport","reset","extendSession"],d=["init","add","remove","track","logEvent","identify","groupIdentify","setGroup","revenue","flush"];function v(e){function t(t,r){e[t]=function(){var n={promise:new Promise((r=>{e._q.push({name:t,args:Array.prototype.slice.call(arguments,0),resolve:r})}))};if(r)return n}}for(var r=0;r<p.length;r++)t(p[r],!1);for(var n=0;n<d.length;n++)t(d[n],!0)}v(r),r.createInstance=function(){var e=r._iq[++r._iqc]={_q:[]};return v(e),e},r._iqc=0,e.amplitude=r}}(window,document)}();

    // Initialize Amplitude
    amplitude.init('YOUR_API_KEY', {
      defaultTracking: {
        sessions: true,
        pageViews: true,
        formInteractions: false,
        fileDownloads: true
      }
    });

    // Track page view
    amplitude.track('Page Viewed', {
      page: window.location.pathname,
      title: document.title
    });
  </script>
</head>
<body>
  <h1>Your Content</h1>

  <button Me</button>

  <script>
    function trackButtonClick() {
      amplitude.track('Button Clicked', {
        buttonName: 'CTA Button',
        location: 'Hero Section'
      });
    }
  </script>
</body>
</html>

EU Data Residency

amplitude.init('YOUR_API_KEY', {
  serverZone: 'EU', // Routes data to EU servers
  serverUrl: 'https://api.eu.amplitude.com/2/httpapi'
});

Method 3: Google Tag Manager Integration

Deploy Amplitude through GTM for centralized tag management:

Step 1: Create Custom HTML Tag

<!-- GTM Tag: Amplitude - Initialize -->
<script>
  (function() {
    // Load Amplitude SDK if not already loaded
    if (typeof amplitude === 'undefined') {
      !function(){"use strict";!function(e,t){var r=e.amplitude||{_q:[],_iq:{}};if(r.invoked)e.console&&console.error&&console.error("Amplitude snippet has been loaded.");else{r.invoked=!0;var n=t.createElement("script");n.type="text/javascript",n.integrity="sha384-x0ik2D45ZDEEEpYpEuDpmj05YY2jEvsdG+FLOw8LkJI4LI/Djj1+qMqAr/AqWXpS",n.crossOrigin="anonymous",n.async=!0,n.src="https://cdn.amplitude.com/libs/analytics-browser-2.0.1-min.js.gz",n.onload=function(){e.amplitude.runQueuedFunctions||console.log("[Amplitude] Error: could not load SDK")};var s=t.getElementsByTagName("script")[0];s.parentNode.insertBefore(n,s);for(var o=function(){return this._q=[],this},i=["add","append","clearAll","prepend","set","setOnce","unset","preInsert","postInsert","remove","getUserProperties"],a=0;a<i.length;a++)o.prototype[i[a]]=function(e){return function(){return this._q.push({name:e,args:Array.prototype.slice.call(arguments,0)}),this}}(i[a]);r.Identify=o;for(var c=function(){this._q=[];return this},u=["getEventProperties","setProductId","setQuantity","setPrice","setRevenue","setRevenueType","setEventProperties"],l=0;l<u.length;l++)c.prototype[u[l]]=function(e){return function(){return this._q.push({name:e,args:Array.prototype.slice.call(arguments,0)}),this}}(u[l]);r.Revenue=c;var p=["getDeviceId","setDeviceId","getSessionId","setSessionId","getUserId","setUserId","setOptOut","setTransport","reset","extendSession"],d=["init","add","remove","track","logEvent","identify","groupIdentify","setGroup","revenue","flush"];function v(e){function t(t,r){e[t]=function(){var n={promise:new Promise((r=>{e._q.push({name:t,args:Array.prototype.slice.call(arguments,0),resolve:r})}))};if(r)return n}}for(var r=0;r<p.length;r++)t(p[r],!1);for(var n=0;n<d.length;n++)t(d[n],!0)}v(r),r.createInstance=function(){var e=r._iq[++r._iqc]={_q:[]};return v(e),e},r._iqc=0,e.amplitude=r}}(window,document)}();
    }

    // Initialize with API key from GTM variable
    amplitude.init({{Amplitude API Key}}, {
      defaultTracking: {
        sessions: true,
        pageViews: false, // Handle manually for better control
        formInteractions: false,
        fileDownloads: true
      },
      logLevel: {{Environment}} === 'production' ? 2 : 1
    });
  })();
</script>

Trigger: All Pages (pageview) - Fire once per page

Step 2: Create Variables

Create the following GTM Variables:

  1. Amplitude API Key (Constant)

    • Type: Constant String
    • Value: Your API key
  2. Environment (Custom JavaScript)

    function() {
      return {{Page Hostname}}.includes('localhost') ? 'development' :
             {{Page Hostname}}.includes('staging') ? 'staging' : 'production';
    }
    

Step 3: Create Event Tracking Tag

<!-- GTM Tag: Amplitude - Track Event -->
<script>
  amplitude.track({{Event Name}}, {
    category: {{Event Category}},
    label: {{Event Label}},
    value: {{Event Value}},
    page: {{Page Path}},
    timestamp: Date.now()
  });
</script>

Trigger: Custom Event (e.g., button_click, form_submit)

Step 4: Create User Identification Tag

<!-- GTM Tag: Amplitude - Identify User -->
<script>
  (function() {
    var userId = {{User ID}};

    if (userId) {
      amplitude.setUserId(userId);

      var identifyEvent = new amplitude.Identify();
      identifyEvent.set('email', {{User Email}});
      identifyEvent.set('plan', {{User Plan}});
      identifyEvent.set('signupDate', {{User Signup Date}});

      amplitude.identify(identifyEvent);
    }
  })();
</script>

Trigger: User Login (custom event)

Method 4: Tag Management System (Tealium/Segment)

If you're using another TMS, you can wrap Amplitude similarly:

// Tealium Custom Container Tag
(function() {
  if (typeof amplitude === 'undefined') {
    // Load SDK...
  }

  amplitude.init(utag_data.amplitude_api_key, {
    defaultTracking: true
  });

  // Track from utag_data
  if (utag_data.event_name) {
    amplitude.track(utag_data.event_name, utag_data.event_properties || {});
  }
})();

Framework-Specific Implementations

React Implementation

Installation

npm install @amplitude/analytics-browser

Create Analytics Context

// src/context/AmplitudeContext.jsx
import React, { createContext, useContext, useEffect } from 'react';
import * as amplitude from '@amplitude/analytics-browser';

const AmplitudeContext = createContext(null);

export const AmplitudeProvider = ({ children, config }) => {
  useEffect(() => {
    // Initialize Amplitude
    amplitude.init(config.apiKey, {
      defaultTracking: config.defaultTracking || {
        sessions: true,
        pageViews: true,
        formInteractions: false,
        fileDownloads: true
      },
      logLevel: config.logLevel || amplitude.Types.LogLevel.Warn,
      serverZone: config.serverZone || 'US'
    });

    return () => {
      // Flush events on unmount
      amplitude.flush();
    };
  }, [config]);

  return (
    <AmplitudeContext.Provider value={amplitude}>
      {children}
    </AmplitudeContext.Provider>
  );
};

export const useAmplitude = () => {
  const context = useContext(AmplitudeContext);
  if (!context) {
    throw new Error('useAmplitude must be used within AmplitudeProvider');
  }
  return context;
};

App Integration

// src/App.js
import React from 'react';
import { AmplitudeProvider } from './context/AmplitudeContext';

const amplitudeConfig = {
  apiKey: process.env.REACT_APP_AMPLITUDE_API_KEY,
  defaultTracking: {
    sessions: true,
    pageViews: true
  },
  logLevel: process.env.NODE_ENV === 'production' ? 2 : 1
};

function App() {
  return (
    <AmplitudeProvider config={amplitudeConfig}>
      <div className="App">
        {/* Your app components */}
      </div>
    </AmplitudeProvider>
  );
}

export default App;

Custom Hook for Tracking

// src/hooks/useAmplitudeTrack.js
import { useCallback } from 'react';
import { useAmplitude } from '../context/AmplitudeContext';

export const useAmplitudeTrack = () => {
  const amplitude = useAmplitude();

  const trackEvent = useCallback((eventName, eventProperties = {}) => {
    amplitude.track(eventName, {
      ...eventProperties,
      timestamp: Date.now(),
      page: window.location.pathname
    });
  }, [amplitude]);

  const identifyUser = useCallback((userId, userProperties = {}) => {
    amplitude.setUserId(userId);

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

    amplitude.identify(identify);
  }, [amplitude]);

  const setUserProperty = useCallback((property, value) => {
    const identify = new amplitude.Identify();
    identify.set(property, value);
    amplitude.identify(identify);
  }, [amplitude]);

  const incrementUserProperty = useCallback((property, value = 1) => {
    const identify = new amplitude.Identify();
    identify.add(property, value);
    amplitude.identify(identify);
  }, [amplitude]);

  return {
    trackEvent,
    identifyUser,
    setUserProperty,
    incrementUserProperty
  };
};

Component Usage

// src/components/SignupButton.jsx
import React from 'react';
import { useAmplitudeTrack } from '../hooks/useAmplitudeTrack';

function SignupButton() {
  const { trackEvent } = useAmplitudeTrack();

  const handleClick = () => {
    trackEvent('Signup Button Clicked', {
      buttonLocation: 'Header',
      buttonColor: 'blue',
      userType: 'new_visitor'
    });

    // Proceed with signup logic
  };

  return (
    <button className="signup-btn">
      Sign Up
    </button>
  );
}

export default SignupButton;

React Router Integration

// src/App.js
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { useAmplitudeTrack } from './hooks/useAmplitudeTrack';

function App() {
  const location = useLocation();
  const { trackEvent } = useAmplitudeTrack();

  useEffect(() => {
    // Track page view on route change
    trackEvent('Page Viewed', {
      page: location.pathname,
      search: location.search,
      hash: location.hash,
      title: document.title
    });
  }, [location, trackEvent]);

  return (
    <Routes>
      {/* Your routes */}
    </Routes>
  );
}

Next.js Implementation

// pages/_app.js
import { useEffect } from 'react';
import { useRouter } from 'next/router';
import * as amplitude from '@amplitude/analytics-browser';

function MyApp({ Component, pageProps }) {
  const router = useRouter();

  useEffect(() => {
    // Initialize Amplitude (client-side only)
    if (typeof window !== 'undefined') {
      amplitude.init(process.env.NEXT_PUBLIC_AMPLITUDE_API_KEY, {
        defaultTracking: {
          sessions: true,
          pageViews: false, // Handle manually
          formInteractions: false,
          fileDownloads: true
        }
      });
    }
  }, []);

  useEffect(() => {
    const handleRouteChange = (url) => {
      amplitude.track('Page Viewed', {
        page: url,
        title: document.title,
        referrer: document.referrer
      });
    };

    // Track initial page view
    handleRouteChange(router.pathname);

    // Track route changes
    router.events.on('routeChangeComplete', handleRouteChange);

    return () => {
      router.events.off('routeChangeComplete', handleRouteChange);
    };
  }, [router]);

  return <Component {...pageProps} />;
}

export default MyApp;

// Create utility file: lib/amplitude.js
import * as amplitude from '@amplitude/analytics-browser';

export const trackEvent = (eventName, eventProperties = {}) => {
  if (typeof window !== 'undefined') {
    amplitude.track(eventName, eventProperties);
  }
};

export const identifyUser = (userId, userProperties = {}) => {
  if (typeof window !== 'undefined') {
    amplitude.setUserId(userId);

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

    amplitude.identify(identify);
  }
};

// Usage in page or component
import { trackEvent } from '../lib/amplitude';

export default function Home() {
  const handleButtonClick = () => {
    trackEvent('CTA Clicked', {
      location: 'Homepage Hero',
      buttonText: 'Get Started'
    });
  };

  return <button Started</button>;
}

Vue.js Implementation

// src/plugins/amplitude.js
import * as amplitude from '@amplitude/analytics-browser';

export default {
  install: (app, options) => {
    // Initialize Amplitude
    amplitude.init(options.apiKey, {
      defaultTracking: options.defaultTracking || {
        sessions: true,
        pageViews: true
      },
      logLevel: options.logLevel || amplitude.Types.LogLevel.Warn
    });

    // Add global properties
    app.config.globalProperties.$amplitude = {
      track: (eventName, eventProperties = {}) => {
        amplitude.track(eventName, eventProperties);
      },
      identify: (userId, userProperties = {}) => {
        amplitude.setUserId(userId);

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

        amplitude.identify(identify);
      },
      setUserProperty: (property, value) => {
        const identify = new amplitude.Identify();
        identify.set(property, value);
        amplitude.identify(identify);
      }
    };

    // Provide for Composition API
    app.provide('amplitude', app.config.globalProperties.$amplitude);
  }
};

// main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import amplitudePlugin from './plugins/amplitude';

const app = createApp(App);

app.use(router);
app.use(amplitudePlugin, {
  apiKey: import.meta.env.VITE_AMPLITUDE_API_KEY,
  defaultTracking: {
    sessions: true,
    pageViews: false // Handle manually via router
  }
});

// Track page views on route change
router.afterEach((to) => {
  app.config.globalProperties.$amplitude.track('Page Viewed', {
    page: to.path,
    title: to.meta.title || document.title,
    params: to.params
  });
});

app.mount('#app');

// Usage in component (Options API)
export default {
  methods: {
    handleClick() {
      this.$amplitude.track('Button Clicked', {
        buttonName: 'Submit',
        page: this.$route.path
      });
    }
  }
};

// Usage in component (Composition API)
import { inject } from 'vue';

export default {
  setup() {
    const amplitude = inject('amplitude');

    const handleClick = () => {
      amplitude.track('Button Clicked', {
        buttonName: 'Submit'
      });
    };

    return { handleClick };
  }
};

Angular Implementation

// src/app/services/amplitude.service.ts
import { Injectable } from '@angular/core';
import * as amplitude from '@amplitude/analytics-browser';
import { environment } from '../../environments/environment';

@Injectable({
  providedIn: 'root'
})
export class AmplitudeService {
  private initialized = false;

  constructor() {
    this.init();
  }

  private init(): void {
    if (this.initialized) return;

    amplitude.init(environment.amplitudeApiKey, {
      defaultTracking: {
        sessions: true,
        pageViews: false, // Handle manually via router
        formInteractions: false,
        fileDownloads: true
      },
      logLevel: environment.production
        ? amplitude.Types.LogLevel.Warn
        : amplitude.Types.LogLevel.Verbose
    });

    this.initialized = true;
  }

  trackEvent(eventName: string, eventProperties?: Record<string, any>): void {
    amplitude.track(eventName, {
      ...eventProperties,
      timestamp: Date.now()
    });
  }

  identifyUser(userId: string, userProperties?: Record<string, any>): void {
    amplitude.setUserId(userId);

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

      amplitude.identify(identify);
    }
  }

  setUserProperty(property: string, value: any): void {
    const identify = new amplitude.Identify();
    identify.set(property, value);
    amplitude.identify(identify);
  }

  incrementProperty(property: string, value: number = 1): void {
    const identify = new amplitude.Identify();
    identify.add(property, value);
    amplitude.identify(identify);
  }

  reset(): void {
    amplitude.reset();
  }
}

// src/app/app.component.ts
import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';
import { AmplitudeService } from './services/amplitude.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
  constructor(
    private router: Router,
    private amplitude: AmplitudeService
  ) {}

  ngOnInit(): void {
    // Track page views on navigation
    this.router.events
      .pipe(filter(event => event instanceof NavigationEnd))
      .subscribe((event: NavigationEnd) => {
        this.amplitude.trackEvent('Page Viewed', {
          page: event.url,
          title: document.title
        });
      });
  }
}

// Usage in component
import { Component } from '@angular/core';
import { AmplitudeService } from '../services/amplitude.service';

@Component({
  selector: 'app-signup',
  template: `<button (click)="handleSignup()">Sign Up</button>`
})
export class SignupComponent {
  constructor(private amplitude: AmplitudeService) {}

  handleSignup(): void {
    this.amplitude.trackEvent('Signup Initiated', {
      source: 'landing_page',
      buttonLocation: 'hero'
    });

    // Signup logic...
  }
}

// environment.ts
export const environment = {
  production: false,
  amplitudeApiKey: 'your-dev-api-key'
};

// environment.prod.ts
export const environment = {
  production: true,
  amplitudeApiKey: 'your-prod-api-key'
};

Mobile & OTT SDKs

iOS Implementation (Swift)

// Install via CocoaPods
// Podfile
platform :ios, '13.0'
use_frameworks!

target 'YourApp' do
  pod 'AmplitudeSwift', '~> 1.0'
end

// Install via Swift Package Manager
// Add package: https://github.com/amplitude/Amplitude-Swift

// AppDelegate.swift
import UIKit
import AmplitudeSwift

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    var amplitude: Amplitude!

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        // Initialize Amplitude
        amplitude = Amplitude(
            configuration: Configuration(
                apiKey: "YOUR_API_KEY",
                defaultTracking: DefaultTrackingOptions(
                    sessions: true,
                    appLifecycles: true,
                    screenViews: true
                ),
                logLevel: .LOG,
                minIdLength: 5,
                partnerId: nil,
                flushQueueSize: 30,
                flushIntervalMillis: 30000,
                instanceName: nil,
                optOut: false,
                storageProvider: nil,
                identifyBatchIntervalMillis: 30000,
                flushMaxRetries: 5,
                serverZone: .US, // or .EU
                serverUrl: nil,
                useBatch: false,
                trackingOptions: TrackingOptions()
            )
        )

        return true
    }
}

// Track event
import AmplitudeSwift

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // Get Amplitude instance
        let amplitude = (UIApplication.shared.delegate as! AppDelegate).amplitude

        // Track event
        amplitude.track(
            eventType: "Screen Viewed",
            eventProperties: [
                "screenName": "Home",
                "category": "main"
            ]
        )
    }

    @IBAction func buttonTapped(_ sender: UIButton) {
        let amplitude = (UIApplication.shared.delegate as! AppDelegate).amplitude

        amplitude.track(
            eventType: "Button Clicked",
            eventProperties: [
                "buttonName": sender.titleLabel?.text ?? "Unknown",
                "screenName": "Home"
            ]
        )
    }
}

// Identify user
func identifyUser(userId: String, email: String, plan: String) {
    let amplitude = (UIApplication.shared.delegate as! AppDelegate).amplitude

    amplitude.setUserId(userId: userId)

    let identify = Identify()
    identify.set(property: "email", value: email)
    identify.set(property: "plan", value: plan)
    identify.set(property: "signupDate", value: ISO8601DateFormatter().string(from: Date()))

    amplitude.identify(identify: identify)
}

// Track revenue
func trackPurchase(productId: String, price: Double, quantity: Int) {
    let amplitude = (UIApplication.shared.delegate as! AppDelegate).amplitude

    let revenue = Revenue()
    revenue.productId = productId
    revenue.price = price
    revenue.quantity = quantity

    amplitude.revenue(revenue: revenue)
}

// Group identification
func setUserGroup(groupType: String, groupName: String) {
    let amplitude = (UIApplication.shared.delegate as! AppDelegate).amplitude

    amplitude.setGroup(groupType: groupType, groupName: groupName)
}

Android Implementation (Kotlin)

// build.gradle (project level)
allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

// build.gradle (app level)
dependencies {
    implementation 'com.amplitude:analytics-android:1.+'
}

// MainApplication.kt
import android.app.Application
import com.amplitude.android.Amplitude
import com.amplitude.android.Configuration
import com.amplitude.android.DefaultTrackingOptions
import com.amplitude.core.LogLevel

class MainApplication : Application() {
    lateinit var amplitude: Amplitude

    override fun onCreate() {
        super.onCreate()

        // Initialize Amplitude
        amplitude = Amplitude(
            Configuration(
                apiKey = "YOUR_API_KEY",
                context = applicationContext,
                defaultTracking = DefaultTrackingOptions(
                    sessions = true,
                    appLifecycles = true,
                    screenViews = true
                ),
                logLevel = LogLevel.DEBUG, // Use LogLevel.WARN in production
                minIdLength = 5,
                flushQueueSize = 30,
                flushIntervalMillis = 30000,
                optOut = false
            )
        )
    }
}

// MainActivity.kt
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.amplitude.android.Amplitude

class MainActivity : AppCompatActivity() {
    private lateinit var amplitude: Amplitude

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Get Amplitude instance
        amplitude = (application as MainApplication).amplitude

        // Track screen view
        amplitude.track("Screen Viewed", mapOf(
            "screenName" to "Home",
            "category" to "main"
        ))
    }

    fun onButtonClick(view: android.view.View) {
        amplitude.track("Button Clicked", mapOf(
            "buttonName" to "Submit",
            "screenName" to "Home"
        ))
    }
}

// Identify user
fun identifyUser(userId: String, email: String, plan: String) {
    val amplitude = (application as MainApplication).amplitude

    amplitude.setUserId(userId)

    amplitude.identify(
        com.amplitude.android.Identify()
            .set("email", email)
            .set("plan", plan)
            .set("signupDate", System.currentTimeMillis())
    )
}

// Track revenue
fun trackPurchase(productId: String, price: Double, quantity: Int) {
    val amplitude = (application as MainApplication).amplitude

    amplitude.revenue(
        com.amplitude.android.Revenue()
            .setProductId(productId)
            .setPrice(price)
            .setQuantity(quantity)
    )
}

// Set user properties
fun updateUserPlan(newPlan: String) {
    val amplitude = (application as MainApplication).amplitude

    amplitude.identify(
        com.amplitude.android.Identify()
            .set("plan", newPlan)
            .add("planUpgrades", 1)
    )
}

React Native Implementation

npm install @amplitude/analytics-react-native
# or
yarn add @amplitude/analytics-react-native

# iOS: Install pods
cd ios && pod install && cd ..
// App.js
import React, { useEffect } from 'react';
import { SafeAreaView, Button, Text } from 'react-native';
import { init, track, Identify, identify, setUserId } from '@amplitude/analytics-react-native';

const App = () => {
  useEffect(() => {
    // Initialize Amplitude
    init('YOUR_API_KEY', {
      defaultTracking: {
        sessions: true,
        appLifecycles: true,
        screenViews: true
      },
      logLevel: __DEV__ ? 1 : 3 // Verbose in dev, Error in production
    });

    // Track app open
    track('App Opened', {
      source: 'direct',
      platform: Platform.OS
    });
  }, []);

  const handleLogin = (userId: string) => {
    setUserId(userId);

    const identifyObj = new Identify();
    identifyObj.set('platform', Platform.OS);
    identifyObj.set('appVersion', '1.0.0');
    identify(identifyObj);

    track('User Logged In', {
      method: 'email'
    });
  };

  const handleButtonPress = () => {
    track('Button Pressed', {
      buttonName: 'Submit',
      screenName: 'Home'
    });
  };

  return (
    <SafeAreaView>
      <Text>Amplitude React Native Example</Text>
      <Button title="Track Event" />
    </SafeAreaView>
  );
};

export default App;

// Create utility hook
// hooks/useAmplitude.js
import { useCallback } from 'react';
import { track, Identify, identify } from '@amplitude/analytics-react-native';

export const useAmplitude = () => {
  const trackEvent = useCallback((eventName, eventProperties = {}) => {
    track(eventName, eventProperties);
  }, []);

  const identifyUser = useCallback((userId, userProperties = {}) => {
    setUserId(userId);

    const identifyObj = new Identify();
    Object.entries(userProperties).forEach(([key, value]) => {
      identifyObj.set(key, value);
    });

    identify(identifyObj);
  }, []);

  return { trackEvent, identifyUser };
};

Server-Side Collection

HTTP API V2

// Node.js Example
const https = require('https');

class AmplitudeServerSide {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.endpoint = 'https://api2.amplitude.com/2/httpapi';
  }

  async track(events) {
    const payload = {
      api_key: this.apiKey,
      events: Array.isArray(events) ? events : [events]
    };

    return new Promise((resolve, reject) => {
      const data = JSON.stringify(payload);

      const options = {
        hostname: 'api2.amplitude.com',
        path: '/2/httpapi',
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Content-Length': data.length
        }
      };

      const req = https.request(options, (res) => {
        let responseData = '';

        res.on('data', (chunk) => {
          responseData += chunk;
        });

        res.on('end', () => {
          if (res.statusCode === 200) {
            resolve(JSON.parse(responseData));
          } else {
            reject(new Error(`HTTP ${res.statusCode}: ${responseData}`));
          }
        });
      });

      req.on('error', reject);
      req.write(data);
      req.end();
    });
  }

  createEvent(userId, eventType, eventProperties = {}, options = {}) {
    return {
      user_id: userId,
      device_id: options.deviceId,
      event_type: eventType,
      event_properties: eventProperties,
      user_properties: options.userProperties,
      time: options.time || Date.now(),
      insert_id: options.insertId || `${userId}-${eventType}-${Date.now()}`,
      session_id: options.sessionId,
      ip: options.ip || '$remote',
      platform: options.platform || 'Web',
      os_name: options.osName,
      os_version: options.osVersion,
      device_brand: options.deviceBrand,
      device_model: options.deviceModel,
      language: options.language,
      country: options.country,
      region: options.region,
      city: options.city
    };
  }
}

// Usage
const amplitude = new AmplitudeServerSide(process.env.AMPLITUDE_API_KEY);

// Track single event
amplitude.track(
  amplitude.createEvent(
    'user-123',
    'Purchase Completed',
    {
      product: 'Premium Plan',
      price: 99.99,
      currency: 'USD'
    },
    {
      insertId: `purchase-${Date.now()}`,
      ip: req.ip,
      userProperties: {
        plan: 'premium',
        totalPurchases: 5
      }
    }
  )
).then(response => {
  console.log('Event tracked:', response);
}).catch(error => {
  console.error('Tracking failed:', error);
});

// Batch track multiple events
const events = [
  amplitude.createEvent('user-123', 'Page Viewed', { page: '/dashboard' }),
  amplitude.createEvent('user-123', 'Button Clicked', { button: 'Export' }),
  amplitude.createEvent('user-123', 'Export Completed', { format: 'CSV' })
];

amplitude.track(events);

Batch API

// For high-volume server-side tracking
class AmplitudeBatch {
  constructor(apiKey, options = {}) {
    this.apiKey = apiKey;
    this.batchSize = options.batchSize || 100;
    this.flushInterval = options.flushInterval || 10000; // 10 seconds
    this.queue = [];
    this.endpoint = 'https://api2.amplitude.com/batch';

    // Auto-flush on interval
    this.intervalId = setInterval(() => this.flush(), this.flushInterval);
  }

  enqueue(event) {
    this.queue.push(event);

    if (this.queue.length >= this.batchSize) {
      this.flush();
    }
  }

  async flush() {
    if (this.queue.length === 0) return;

    const events = this.queue.splice(0, this.batchSize);

    const payload = {
      api_key: this.apiKey,
      events: events
    };

    try {
      const response = await fetch(this.endpoint, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload)
      });

      if (!response.ok) {
        console.error('Batch flush failed:', await response.text());
        // Re-queue events on failure
        this.queue.unshift(...events);
      }
    } catch (error) {
      console.error('Batch flush error:', error);
      this.queue.unshift(...events);
    }
  }

  destroy() {
    clearInterval(this.intervalId);
    this.flush();
  }
}

// Usage
const batch = new AmplitudeBatch(process.env.AMPLITUDE_API_KEY, {
  batchSize: 50,
  flushInterval: 5000
});

// Enqueue events
batch.enqueue({
  user_id: 'user-123',
  event_type: 'API Call',
  event_properties: { endpoint: '/api/users', method: 'GET' }
});

// Graceful shutdown
process.on('SIGTERM', () => {
  batch.destroy();
});

Configuration Options

Browser SDK Configuration

import * as amplitude from '@amplitude/analytics-browser';

amplitude.init('YOUR_API_KEY', {
  // User/Device Identification
  userId: 'user-123', // Optional: Set on init
  deviceId: 'device-abc', // Optional: Custom device ID

  // Tracking Options
  defaultTracking: {
    sessions: true, // Auto-track sessions
    pageViews: true, // Auto-track page views
    formInteractions: false, // Track form events
    fileDownloads: true // Track download links
  },

  // Server Configuration
  serverUrl: 'https://api2.amplitude.com/2/httpapi', // Default US
  serverZone: 'US', // 'US' or 'EU'
  useBatch: false, // Use batch endpoint

  // Flush Configuration
  flushIntervalMillis: 10000, // Flush every 10 seconds
  flushQueueSize: 30, // Flush when queue reaches 30 events
  flushMaxRetries: 5, // Retry failed requests up to 5 times

  // Identity
  minIdLength: 5, // Minimum user/device ID length
  partnerId: 'your-partner-id', // Optional partner ID

  // Session Configuration
  sessionTimeout: 30 * 60 * 1000, // 30 minutes

  // Tracking Options
  trackingOptions: {
    ipAddress: true,
    language: true,
    platform: true,
    osName: true,
    osVersion: true,
    deviceManufacturer: true,
    deviceModel: true
  },

  // Transport
  transport: 'fetch', // 'fetch' or 'xhr' or 'beacon'

  // Logging
  logLevel: amplitude.Types.LogLevel.Warn, // None, Error, Warn, Verbose, Debug

  // Opt Out
  optOut: false,

  // Callbacks
  onBeforeEventSend: (event) => {
    // Modify or drop events before sending
    if (event.event_type === 'Internal Event') {
      return null; // Drop event
    }
    return event;
  }
});

Verifying Installation

Browser Console Checks

// Check if Amplitude is loaded
console.log(typeof amplitude !== 'undefined' ? 'Amplitude loaded' : 'Not loaded');

// Get current session ID
amplitude.getSessionId().promise.then(sessionId => {
  console.log('Session ID:', sessionId);
});

// Get device ID
amplitude.getDeviceId().promise.then(deviceId => {
  console.log('Device ID:', deviceId);
});

// Get user ID
amplitude.getUserId().promise.then(userId => {
  console.log('User ID:', userId);
});

// Test track event
amplitude.track('Test Event', {
  property1: 'value1',
  property2: 'value2'
}).promise.then(result => {
  console.log('Event tracked:', result);
});

Network Tab Verification

  1. Open DevTools (F12) > Network tab
  2. Filter by "amplitude" or "api2.amplitude.com"
  3. Look for POST requests to:
    • https://api2.amplitude.com/2/httpapi (standard)
    • https://api2.amplitude.com/batch (batch mode)
  4. Check request payload:
    • Contains api_key
    • Contains events array
    • Events have event_type, user_id or device_id

Amplitude Debugger

  1. Install Amplitude Instrumentation Explorer Chrome extension
  2. Navigate to your site
  3. Open extension
  4. Verify:
    • Events appear in real-time
    • Event properties are correct
    • User properties are set

Live Events in Amplitude

  1. Log into Amplitude
  2. Navigate to User Look-Up
  3. Search for your test user ID or device ID
  4. Click on user > Event Stream
  5. Verify events appear within seconds

Common Installation Issues

Issue Symptoms Solution
Events not sending No network requests Check API key is correct, verify SDK initialized, check console for errors
Wrong API key Events don't appear in Amplitude Verify environment-specific keys, check project selection in Amplitude
CORS errors Console shows CORS blocked Amplitude endpoints should allow CORS; check for proxy/firewall issues
Duplicate events Same event tracked multiple times Check for multiple init calls, use unique insert_id for deduplication
Missing user_id Events tracked with device_id only Call setUserId() after authentication, verify user ID not null/undefined
Session not starting New session on every event Check session timeout settings, verify cookies not blocked
EU data residency Data not in EU Set serverZone: 'EU' in configuration
Events delayed Events appear after long delay Check flushInterval and flushQueueSize settings, call flush() manually if needed
Type errors (TypeScript) Import errors Install @types or update to latest SDK version with built-in types
Mobile events missing iOS/Android events don't appear Verify SDK initialization, check API key, review app permissions

Debug Mode

// Enable verbose logging
amplitude.init('YOUR_API_KEY', {
  logLevel: amplitude.Types.LogLevel.Debug
});

// Manual flush for testing
amplitude.flush().promise.then(() => {
  console.log('All events flushed');
});

// Set custom logger
amplitude.init('YOUR_API_KEY', {
  loggerProvider: {
    log: (message) => console.log('[Amplitude]', message),
    error: (message) => console.error('[Amplitude Error]', message),
    warn: (message) => console.warn('[Amplitude Warning]', message),
    debug: (message) => console.debug('[Amplitude Debug]', message)
  }
});

Security Best Practices

API Key Protection

// Use environment variables
const AMPLITUDE_API_KEY = process.env.REACT_APP_AMPLITUDE_API_KEY;

// Never commit API keys
// .env
REACT_APP_AMPLITUDE_API_KEY=your_api_key_here

// .gitignore
.env
.env.local

PII Handling

// DON'T: Track PII directly
amplitude.track('User Signup', {
  email: 'user@example.com', // BAD
  phone: '555-1234' // BAD
});

// DO: Hash or pseudonymize
import crypto from 'crypto';

const hashValue = (value) => {
  return crypto.createHash('sha256').update(value).digest('hex');
};

amplitude.track('User Signup', {
  emailHash: hashValue('user@example.com'), // GOOD
  userIdHash: hashValue('user-123') // GOOD
});

Data Filtering

// Filter sensitive data before sending
amplitude.init('YOUR_API_KEY', {
  onBeforeEventSend: (event) => {
    // Remove sensitive properties
    const sensitiveKeys = ['password', 'ssn', 'credit_card'];

    if (event.event_properties) {
      sensitiveKeys.forEach(key => {
        delete event.event_properties[key];
      });
    }

    return event;
  }
});
// Wait for consent before initializing
let amplitudeInitialized = false;

window.addEventListener('cookieConsentGiven', (event) => {
  if (event.detail.analytics && !amplitudeInitialized) {
    amplitude.init('YOUR_API_KEY', {
      defaultTracking: { sessions: true, pageViews: true }
    });
    amplitudeInitialized = true;
  }
});

// Opt-out capability
function optOutOfTracking() {
  amplitude.setOptOut(true);
}

function optInToTracking() {
  amplitude.setOptOut(false);
}

Performance Considerations

Lazy Loading

// Load Amplitude only when needed
let amplitudeLoaded = false;

async function loadAmplitude() {
  if (amplitudeLoaded) return;

  const { default: amplitude } = await import('@amplitude/analytics-browser');

  amplitude.init('YOUR_API_KEY');
  amplitudeLoaded = true;

  return amplitude;
}

// Use on user interaction
document.addEventListener('scroll', async () => {
  const amplitude = await loadAmplitude();
  amplitude.track('User Engaged');
}, { once: true });

Batching Events

// Configure batching for better performance
amplitude.init('YOUR_API_KEY', {
  useBatch: true, // Use batch endpoint
  flushQueueSize: 50, // Batch up to 50 events
  flushIntervalMillis: 10000 // Flush every 10 seconds
});

Defer Non-Critical Tracking

// Use requestIdleCallback for low-priority events
function trackLowPriority(eventName, props) {
  if ('requestIdleCallback' in window) {
    requestIdleCallback(() => {
      amplitude.track(eventName, props);
    });
  } else {
    setTimeout(() => {
      amplitude.track(eventName, props);
    }, 1);
  }
}

Deployment Strategy

  • Load the Browser SDK with environment-specific API keys; disable automatic tracking you do not need (e.g., form interactions).
  • Use a consent wrapper to delay init when required; set tracking options explicitly to avoid surprise events.
  • Consider using a first-party proxy for ingestion to reduce blocking.

Tag Manager Deployment

  • Store API keys and ingest endpoints as variables in the TMS; deploy init and event helpers through templates.
  • Ensure the init tag fires early enough to capture attribution but after consent if needed.
  • Create reusable TMS macros for common events (commerce, feature usage) to keep mappings consistent.

Direct Embed or Hard-Coded Scripts

  • Embed the script in the head to establish device_id early and store attribution (utm, referrer) before SPA navigation.
  • Register identify/setUserProperties after authentication to bind traits to the known user_id.

Validation Checklist

  • Use Event Stream/Monitor to inspect payloads; ensure event volumes align with expectations after each release.
  • Verify attribution fields (utm_*, referrer) and session_id values appear on key events.

Configuration Recommendations

Merged Users: Enable merged users (Project Settings → User Management) only if you need cross-device identity resolution. Once enabled, it retroactively merges historical anonymous profiles with identified users, which can alter historical funnel and retention reports. Test in a development project first.

Ingestion Filtering: If you track high-volume events (page scrolls, mouse movements), use Amplitude's ingestion filters (Settings → Project → Ingestion Filters) to drop or sample noisy events before they count against your event quota. Filter at ingestion rather than in queries to save quota.

Environment Separation: Use separate Amplitude projects for production and development. Never share API keys between environments. Use amplitude.init('API_KEY', { serverZone: 'US' }) for US data center or serverZone: 'EU' for EU data residency (available on Growth and Enterprise plans).

First-Party Proxy: Set up a first-party proxy (api.yourdomain.com/amplitude) to route events through your domain and bypass ad blockers. Amplitude provides proxy setup guides for Cloudflare, Nginx, and AWS CloudFront.