Scripts

PostHog is an open-source product analytics platform that provides analytics, session replay, feature flags, A/B testing, and more.

Nuxt Scripts provides a registry script composable useScriptPostHog() to easily integrate PostHog in your Nuxt app.

Installation

You must install the posthog-js dependency:

pnpm add posthog-js

Script Stats

Loading
NPM
First-Party
Supported
Bundling
No
Privacy
No data collected
Tracked Data
Page Views Events Conversions User Identity Session Replay Heatmaps A/B Testing

Nuxt Config Setup

The simplest way to load PostHog globally in your Nuxt App is to use Nuxt config. Alternatively you can directly use the useScriptPostHog composable.

export default defineNuxtConfig({
  scripts: {
    registry: {
      posthog: {
        apiKey: 'phc_xxxxxxxxxxxxxxxxx'
      }
    }
  }
})

useScriptPostHog

The useScriptPostHog composable lets you have fine-grain control over when and how PostHog is loaded on your site.

const { proxy } = useScriptPostHog()

proxy.posthog.capture('conversion', { value: 1 })

Please follow the Registry Scripts guide to learn more about advanced usage.

First-Party Mode

This script supports First-Party Mode which routes all traffic through your domain for improved privacy and ad blocker bypass.

export default defineNuxtConfig({
  scripts: {
    firstParty: true,
    registry: {
      posthog: { apiKey: 'phc_xxxxxxxxxxxxxxxxx'}
    }
  }
})

To opt-out for this specific script:

useScriptPostHog({
  apiKey: 'phc_xxxxxxxxxxxxxxxxx',
  scriptOptions: {
    firstParty: false
  }
})

Example

Using PostHog only in production while using the proxy to send events.

ConversionButton.vue
<script setup lang="ts">
const { proxy } = useScriptPostHog()

// noop in development, ssr
// just works in production, client
function handleAction() {
  proxy.posthog.capture('conversion', { value: 1 })
}
</script>

<template>
  <div>
    <button @click="handleAction">
      Send Event
    </button>
  </div>
</template>

PostHogApi

import type { PostHog } from 'posthog-js'

export interface PostHogApi {
  posthog: PostHog
}

Config Schema

export const PostHogOptions = object({
  apiKey: string(),
  region: optional(union([literal('us'), literal('eu')])),
  apiHost: optional(string()), // Custom API host URL (e.g. '/ph' for reverse proxy)
  autocapture: optional(boolean()),
  capturePageview: optional(union([boolean(), literal('history_change')])),
  capturePageleave: optional(boolean()),
  disableSessionRecording: optional(boolean()),
  config: optional(record(string(), any())), // Full PostHogConfig passthrough
})

EU Hosting

To use PostHog's EU cloud:

export default defineNuxtConfig({
  scripts: {
    registry: {
      posthog: {
        apiKey: 'YOUR_API_KEY',
        region: 'eu'
      }
    }
  }
})

First-Party Proxy

When first-party mode is enabled, PostHog requests are automatically proxied through your own server. This improves event capture reliability by avoiding ad blockers. No privacy anonymization is applied — PostHog is a trusted, open-source tool that requires full-fidelity data for GeoIP enrichment, feature flags, and session replay.

No additional configuration is needed — the module automatically sets apiHost to route through your server's proxy endpoint:

export default defineNuxtConfig({
  scripts: {
    firstParty: true, // enabled by default
    registry: {
      posthog: {
        apiKey: 'YOUR_API_KEY',
        // apiHost is auto-set to '/_proxy/ph' (or '/_proxy/ph-eu' for EU region)
      }
    }
  }
})

The proxy handles both API requests and static assets (e.g. session recording SDK), routing them to the correct PostHog endpoints.

Custom API Host

To use a custom reverse proxy or self-hosted PostHog instance, set apiHost directly:

export default defineNuxtConfig({
  scripts: {
    registry: {
      posthog: {
        apiKey: 'YOUR_API_KEY',
        apiHost: '/my-proxy'
      }
    }
  }
})

The apiHost option accepts any URL or relative path, overriding both the region default and the first-party proxy auto-configuration. For additional PostHog SDK options like ui_host, use the config passthrough.

Feature Flags

Feature flag methods return values, so you need to wait for PostHog to load first:

const { onLoaded } = useScriptPostHog()

onLoaded(({ posthog }) => {
  // Check a feature flag
  if (posthog.isFeatureEnabled('new-dashboard')) {
    // Show new dashboard
  }

  // Get flag payload
  const payload = posthog.getFeatureFlagPayload('experiment-config')
})

Disabling Session Recording

export default defineNuxtConfig({
  scripts: {
    registry: {
      posthog: {
        apiKey: 'YOUR_API_KEY',
        disableSessionRecording: true
      }
    }
  }
})