Umami Integrations | OpsBlu Docs

Umami Integrations

Connect Umami with third-party tools — CRM, marketing, CMS, and data warehouse integration guides.

Integration Overview

Umami offers extensive integration capabilities through its API, npm packages, hosting options, and framework support. Whether you're self-hosting or using Umami Cloud, these integrations enable seamless connection with your development workflow and tech stack.

Hosting Platforms

Vercel

One-Click Deploy:

Deploy with Vercel

Manual Setup:

# Clone repository
git clone https://github.com/umami-software/umami.git
cd umami

# Install dependencies
npm install

# Set environment variables in Vercel dashboard
DATABASE_URL=postgresql://...
HASH_SALT=your-random-salt

# Deploy
vercel deploy

Railway

One-Click Deploy:

# Deploy using Railway CLI
railway up

# Or use Railway button
# https://railway.app/new/template/umami

Environment Variables:

DATABASE_URL=postgresql://...
HASH_SALT=random-string-32-chars
PORT=3000

Netlify

# Install Netlify CLI
npm install -g netlify-cli

# Deploy
netlify deploy --prod

# Configure environment variables in Netlify dashboard

Docker

Docker Compose:

version: '3'
services:
  umami:
    image: ghcr.io/umami-software/umami:postgresql-latest
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://umami:umami@db:5432/umami
      DATABASE_TYPE: postgresql
      HASH_SALT: replace-me-with-a-random-string
    depends_on:
      - db
    restart: always

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: umami
      POSTGRES_USER: umami
      POSTGRES_PASSWORD: umami
    volumes:
      - umami-db-data:/var/lib/postgresql/data
    restart: always

volumes:
  umami-db-data:

Run with Docker Compose:

docker-compose up -d

DigitalOcean

Deploy as a DigitalOcean App:

# Create app.yaml
spec:
  name: umami
  services:
  - name: web
    github:
      repo: your-username/umami
      branch: master
    build_command: npm run build
    run_command: npm start
    envs:
    - key: DATABASE_URL
      value: ${db.DATABASE_URL}
    - key: HASH_SALT
      value: your-random-salt
  databases:
  - name: db
    engine: PG
    version: "15"

Framework Integrations

Next.js

Installation:

npm install @umami/node

App Router (Next.js 13+):

// app/layout.js
import Script from 'next/script'

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        <Script
          async
          src="https://cloud.umami.is/script.js"
          data-website-id="your-website-id"
          strategy="afterInteractive"
        />
      </head>
      <body>{children}</body>
    </html>
  )
}

Pages Router:

// pages/_app.js
import Script from 'next/script'

function MyApp({ Component, pageProps }) {
  return (
    <>
      <Script
        async
        src="https://cloud.umami.is/script.js"
        data-website-id="your-website-id"
        strategy="afterInteractive"
      />
      <Component {...pageProps} />
    </>
  )
}

Track Events:

'use client'

export default function Component() {
  const handleClick = () => {
    umami.track('button-click', { location: 'homepage' })
  }

  return <button Me</button>
}

React

npm install @umami/react
import { UmamiProvider, useUmami } from '@umami/react'

function App() {
  return (
    <UmamiProvider
      websiteId="your-website-id"
      src="https://cloud.umami.is/script.js"
    >
      <YourApp />
    </UmamiProvider>
  )
}

function Component() {
  const umami = useUmami()

  const handleEvent = () => {
    umami.track('event-name', { property: 'value' })
  }

  return <button Event</button>
}

Vue.js / Nuxt

Nuxt 3:

// plugins/umami.client.js
export default defineNuxtPlugin(() => {
  const script = document.createElement('script')
  script.async = true
  script.src = 'https://cloud.umami.is/script.js'
  script.setAttribute('data-website-id', 'your-website-id')
  document.head.appendChild(script)
})

Vue 3 Composition API:

// composables/useUmami.js
export const useUmami = () => {
  const track = (event, data) => {
    if (typeof window !== 'undefined' && window.umami) {
      window.umami.track(event, data)
    }
  }

  return { track }
}

// Usage in component
const { track } = useUmami()
track('button-click', { page: 'home' })

SvelteKit

// src/routes/+layout.svelte
<script>
  import { onMount } from 'svelte'

  onMount(() => {
    const script = document.createElement('script')
    script.async = true
    script.src = 'https://cloud.umami.is/script.js'
    script.dataset.websiteId = 'your-website-id'
    document.head.appendChild(script)
  })
</script>

<!-- Track events -->
<button on:click={() => umami.track('click')}>
  Track Click
</button>

Gatsby

npm install gatsby-plugin-umami
// gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: 'gatsby-plugin-umami',
      options: {
        websiteId: 'your-website-id',
        srcUrl: 'https://cloud.umami.is/script.js',
        includeInDevelopment: false,
        autoTrack: true,
        respectDoNotTrack: true
      }
    }
  ]
}

Content Management Systems

WordPress

Manual Installation:

// Add to theme's functions.php or use Code Snippets plugin
function add_umami_tracking() {
    ?>
    <script async
      src="https://cloud.umami.is/script.js"
      data-website-id="your-website-id">
    </script>
    <?php
}
add_action('wp_head', 'add_umami_tracking');

Using Plugin:

Search for "Umami Analytics" in WordPress plugin directory and install.

Ghost

// Settings > Code Injection > Site Header
<script async
  src="https://cloud.umami.is/script.js"
  data-website-id="your-website-id">
</script>

Webflow

  1. Go to Project Settings > Custom Code
  2. Add to Head Code:
<script async
  src="https://cloud.umami.is/script.js"
  data-website-id="your-website-id">
</script>

API Integration

Authentication

# Get API token
curl -X POST https://your-umami.com/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"your-password"}'

# Response includes token
{"token":"your-api-token"}

Fetch Website Stats

# Get website statistics
curl "https://your-umami.com/api/websites/WEBSITE_ID/stats?startAt=1640000000000&endAt=1672000000000" \
  -H "Authorization: Bearer YOUR_TOKEN"

Get Events

# Fetch events data
curl "https://your-umami.com/api/websites/WEBSITE_ID/events?startAt=1640000000000&endAt=1672000000000" \
  -H "Authorization: Bearer YOUR_TOKEN"

Node.js SDK

npm install @umami/node
const { UmamiClient } = require('@umami/node')

const client = new UmamiClient({
  apiUrl: 'https://your-umami.com',
  token: 'YOUR_API_TOKEN'
})

// Get website stats
const stats = await client.getWebsiteStats(websiteId, {
  startAt: Date.now() - 7 * 24 * 60 * 60 * 1000, // 7 days ago
  endAt: Date.now()
})

// Get active users
const activeUsers = await client.getActiveUsers(websiteId)

// Get events
const events = await client.getEvents(websiteId, {
  startAt: Date.now() - 24 * 60 * 60 * 1000 // 24 hours
})

Database Integrations

PostgreSQL

# Connection string format
DATABASE_URL=postgresql://username:password@host:5432/database

# With SSL
DATABASE_URL=postgresql://username:password@host:5432/database?sslmode=require

MySQL

# Connection string format
DATABASE_URL=mysql://username:password@host:3306/database

# With SSL
DATABASE_URL=mysql://username:password@host:3306/database?ssl={"rejectUnauthorized":true}

Automation and Webhooks

Zapier Integration

Create custom Zapier integration using webhooks:

  1. Set up webhook trigger in Zapier
  2. Configure Umami to send event data to webhook URL
  3. Connect to 5000+ apps via Zapier

Custom Webhooks

// Send events to external webhook
async function sendToWebhook(event, data) {
  await fetch('https://your-webhook.com/endpoint', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      event: event,
      data: data,
      timestamp: new Date().toISOString()
    })
  })

  // Also track in Umami
  umami.track(event, data)
}

Data Export and Reporting

CSV Export

// Export data programmatically
const stats = await client.getWebsiteStats(websiteId, dateRange)
const csv = convertToCSV(stats)
fs.writeFileSync('analytics-report.csv', csv)

Google Sheets Integration

Use Google Apps Script to pull Umami data:

function importUmamiData() {
  const response = UrlFetchApp.fetch(
    'https://your-umami.com/api/websites/ID/stats',
    {
      headers: { 'Authorization': 'Bearer TOKEN' }
    }
  )

  const data = JSON.parse(response.getContentText())
  // Write to Google Sheet
  const sheet = SpreadsheetApp.getActiveSheet()
  sheet.getRange(1, 1).setValue(data.pageviews)
}

Reverse Proxy Setup

Nginx

server {
  listen 80;
  server_name analytics.yourdomain.com;

  location / {
    proxy_pass http://localhost:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}

Apache

<VirtualHost *:80>
  ServerName analytics.yourdomain.com

  ProxyPreserveHost On
  ProxyPass / http://localhost:3000/
  ProxyPassReverse / http://localhost:3000/
</VirtualHost>