Integrations

Google Analytics

Google Analytics
BackendStableHybrid

Send analytics data to Google Analytics 4 via Measurement Protocol. Supports server-side tracking with client-side page views.

Nextlytics is a server-side analytics library for Next.js. No client JavaScript, no cookies, GDPR compliant. Learn more →

Configuration

import { Nextlytics } from "@nextlytics/core/server";
import { googleAnalyticsBackend } from "@nextlytics/core/backends/ga";
 
export const { middleware, analytics } = Nextlytics({
  backends: [
    googleAnalyticsBackend({
      // Required. Your GA4 Measurement ID.
      // Find it: GA4 Admin -> Data Streams -> Your Stream -> Measurement ID
      measurementId: "G-XXXXXXXXXX",
 
      // Optional but recommended for Measurement Protocol delivery.
      // Required for server-origin custom events, and for client-origin custom
      // events when preferClientSideForClientEvents is false.
      // Find it: GA4 Admin -> Data Streams -> Measurement Protocol API secrets
      apiSecret: "your-api-secret",
 
      // Optional. Shows events in GA4 DebugView for testing.
      // Default: false
      debugMode: false,
 
      // Optional. Source for GA client_id.
      // - "gaCookie" (default): Use _ga cookie set by gtag.js, fall back to anonymousUserId
      // - "anonymousUserId": Always use Nextlytics anonymousUserId
      clientIdSource: "gaCookie",
 
      // Optional. For client-origin custom events:
      // - true (default): send via gtag in browser
      // - false: send via Measurement Protocol (requires apiSecret)
      preferClientSideForClientEvents: true,
    }),
  ],
});

Event Mapping

Google Analytics requires page views to come from the browser. It needs to run JavaScript to collect browser metadata and measure engagement. Because of this limitation, Nextlytics uses a hybrid approach:

  • Page views are sent client-side via a JavaScript snippet
  • Server-origin custom events are sent via Measurement Protocol when apiSecret is configured
  • Client-origin custom events are sent client-side by default

Page View Events

When Nextlytics tracks a pageView, it returns a small JavaScript snippet that fires gtag.js. By default, the snippet uses the _ga cookie (set by gtag.js on previous visits) as the GA client_id. On the first visit when no _ga cookie exists yet, it falls back to the Nextlytics anonymousUserId.

The snippet maps to GA4's page_view event.

Other Events

Custom events (purchases, form submissions, API/server events) can be delivered in two modes:

  • Server-origin events use Measurement Protocol when apiSecret is configured.
  • Client-origin events use gtag('event', ...) by default.

To force Measurement Protocol for client-origin events too, set preferClientSideForClientEvents: false and provide apiSecret.

const { analytics } = await import("./nextlytics");
const api = await analytics();
 
await api.sendEvent("purchase", {
  props: {
    value: 99.99,
    currency: "USD",
  },
});

Event names are converted from camelCase to snake_case:

  • formSubmission -> form_submission
  • apiCall -> api_call
  • userSignup -> user_signup

User Identification

User identification is configured via the callbacks.getUser option in your Nextlytics config. When a user is identified, Nextlytics sends only user_id to GA4. For privacy, email, name, and phone are not sent. Custom traits are sent as user properties.

export const { middleware, analytics } = Nextlytics({
  callbacks: {
    getUser: async (ctx) => {
      const session = await getSession(ctx);
      if (!session?.user) return undefined;
      return {
        userId: session.user.id,
        traits: {
          plan: "pro",      // Sent as GA4 user property
          company: "Acme",  // Sent as GA4 user property
          email: "...",     // NOT sent to GA
          name: "...",      // NOT sent to GA
        },
      };
    },
  },
  backends: [googleAnalyticsBackend({ ... })],
});

Limitations

  • First visit uses fallback client_id. On the very first page view, the _ga cookie doesn't exist yet (gtag.js hasn't run). Nextlytics falls back to anonymousUserId for that request. Subsequent requests use the real _ga cookie.
  • Page views require JavaScript. This is a GA limitation, not Nextlytics.
  • Real-time reports may be delayed. Measurement Protocol events can take a few minutes to appear in GA4.

Debugging

Enable debugMode to see events in GA4's DebugView:

googleAnalyticsBackend({
  measurementId: "G-XXXXXXXXXX",
  apiSecret: "xxx",
  debugMode: true,
});

Then open GA4 -> Admin -> DebugView to see incoming events.

Ready to add server-side analytics?

Get started with Nextlytics in 3 simple steps.