Skip to main content
Code auditCheck every pull request for privacy riskWebsite auditCatch scripts and vendors that appear in productionInth AgentAsk what changed and follow the answer to its sourceCookie consentFast consent that lives in your codebase
AboutHandbookBlogOSS
AI feature reviewsFundraising Due DiligencePrivacy impact reviewsEnterprise customer reviewsCookie and tracking audits
Pricing
Sign inRun a free scan
Run a free scan
Back to the blog

Published July 15, 2026

How to integrate Meta Pixel in Next.js with c15t

KW

Kaylee Williams

Founding Engineer

Add Meta Pixel to a Next.js App Router project with c15t so the pixel loads only after marketing consent, then track page views and conversion events safely.

Topic
Guides
Reading time
4 min read

Meta Pixel measures ad conversions and audience activity, but it should not run before the visitor has made the required consent choice. In a Next.js App Router project, c15t can own the pixel lifecycle so Meta Pixel loads only after marketing consent is granted.

By the end, you will be able to install the c15t packages, register Meta Pixel in the c15t provider, track standard events from client components, track App Router navigation, and add Meta Data Processing Options when your legal team requires them. This guide is Next.js-specific; examples use @c15t/nextjs and App Router APIs from next/navigation.

Install the packages

You need a Next.js App Router project, a c15t backend URL, and a Meta Pixel ID from Events Manager. Install c15t, the Next.js adapter, and the script integration package. If you use the prebuilt banner and dialog, import @c15t/nextjs/styles.css from app/globals.css.

npm install @c15t/nextjs @c15t/scripts
pnpm add @c15t/nextjs @c15t/scripts
yarn add @c15t/nextjs @c15t/scripts
bun add @c15t/nextjs @c15t/scripts

Register Meta Pixel in the c15t provider

Create a client provider and pass the metaPixel helper through the scripts option. The c15t Meta Pixel integration uses the marketing category. It waits for marketing consent, queues fbq('consent', 'grant'), initializes the pixel, tracks the default PageView, and loads Meta's fbevents.js. If consent is revoked later, c15t calls Meta's consent-revoke API, which instructs Meta to pause Pixel fires. Use an absolute hosted backend URL unless you have configured a Next.js rewrite for a relative path such as /api/c15t; a fresh app will otherwise return 404 for that path. Do not also load Meta Pixel with next/script or a separate tag manager rule, because that bypasses the lifecycle c15t is managing.

// components/consent-manager/provider.tsx
'use client';

import { type ReactNode } from 'react';
import {
  ConsentBanner,
  ConsentDialog,
  ConsentManagerProvider,
} from '@c15t/nextjs';
import { metaPixel } from '@c15t/scripts/meta-pixel';

const scripts = [
  metaPixel({
    pixelId: '123456789012345',
  }),
];

export function ConsentProvider({ children }: { children: ReactNode }) {
  return (
    <ConsentManagerProvider
      options={{
        mode: 'hosted',
        backendURL: 'http://your-project.inth.app',
        scripts,
      }}
    >
      <ConsentBanner />
      <ConsentDialog />
      {children}
    </ConsentManagerProvider>
  );
}

Track conversion events from client components

The imported metaPixelEvent and metaPixelCustomEvent helpers always exist, but they call window.fbq. Before the visitor grants marketing consent for the first time, window.fbq is unavailable, so invoking a helper can throw. Call the helpers only from client components, effects, or event handlers, and guard event calls with useConsentManager().has('marketing') so your app does not call the pixel when consent is missing or revoked.

// components/add-to-cart-button.tsx
'use client';

import { useConsentManager } from '@c15t/nextjs';
import { metaPixelEvent } from '@c15t/scripts/meta-pixel';

type AddToCartButtonProps = {
  sku: string;
  price: number;
  currency: string;
};

export function AddToCartButton({ sku, price, currency }: AddToCartButtonProps) {
  const { has } = useConsentManager();

  function handleClick() {
    // Add the item to your cart first.

    if (has('marketing')) {
      metaPixelEvent('AddToCart', {
        content_ids: [sku],
        content_type: 'product',
        value: price,
        currency,
      });
    }
  }

  return <button onClick={handleClick}>Add to cart</button>;
}

Use metaPixelEvent('Lead', ...), metaPixelEvent('Purchase', ...), and other standard events for Meta's built-in event names. When you deduplicate browser events against Conversions API events, pass an event ID as the third argument, for example metaPixelEvent('Purchase', { value: 149.97, currency: 'USD' }, { eventID: 'browser-event-123' }). Use metaPixelCustomEvent only when no standard event fits.

Track App Router page views

The default setup sends PageView when the pixel loads. For client-side navigation, disable the install-time page view and emit one when the route changes and marketing consent is granted. Use usePathname() and useSearchParams() from next/navigation to observe App Router URL changes. If you use useSearchParams() on statically rendered routes, wrap the tracking component in Suspense, as the Next.js docs recommend.

// components/consent-manager/provider.tsx
import { Suspense } from 'react';

const scripts = [
  metaPixel({
    pixelId: '123456789012345',
    trackPageView: false,
  }),
];

// Render inside ConsentManagerProvider:
<Suspense fallback={null}>
  <MetaRouteTracking />
</Suspense>

// components/meta-route-tracking.tsx
'use client';

import { useEffect } from 'react';
import { usePathname, useSearchParams } from 'next/navigation';
import { useConsentManager } from '@c15t/nextjs';
import { metaPixelEvent } from '@c15t/scripts/meta-pixel';

export function MetaRouteTracking() {
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const { has } = useConsentManager();

  useEffect(() => {
    if (has('marketing')) {
      metaPixelEvent('PageView');
    }
  }, [has, pathname, searchParams]);

  return null;
}

Add Data Processing Options if they apply

Meta supports Data Processing Options for US users, including Limited Data Use. c15t exposes this through dataProcessingOptions and queues the call before fbq('init', ...). Ask your legal or privacy team which setting applies.

import { metaPixel } from '@c15t/scripts/meta-pixel';

const scripts = [
  metaPixel({
    pixelId: '123456789012345',
    dataProcessingOptions: {
      options: ['LDU'],
      country: 0,
      state: 0,
    },
  }),
];

Check the integration

Test in a fresh browser profile. Reject marketing consent and confirm fbevents.js does not load. Grant marketing consent and confirm fbevents.js loads and Meta receives the expected PageView. Trigger a conversion event and confirm it appears in Meta Events Manager. Revoke marketing consent and confirm your guarded event handlers stop calling metaPixelEvent. Also check that no separate next/script tag or tag manager rule initializes the same pixel.

Privacy notes for review

This section is legal information for implementation planning, not legal advice. The ICO's PECR guidance says non-essential cookies and similar technologies need consent unless an exemption applies, and GDPR or UK GDPR duties can also apply when the pixel processes personal data. Meta's GDPR guidance documents fbq('consent', 'revoke') and fbq('consent', 'grant') as the API for pausing and later sending Pixel fires. For EU and UK visitors, avoid loading Meta Pixel before the required consent has been collected. Review the final notice, consent model, Meta configuration, and US state privacy settings with counsel before production. Sources: c15t Meta Pixel integration, c15t Next.js script loader, Next.js route change example, ICO cookies and similar technologies guidance, ICO consent guidance, Meta Pixel GDPR guidance, and Meta Data Processing Options.

Next steps

You have registered Meta Pixel in c15t, gated it behind marketing consent, tracked conversion events from client components, handled App Router page views, and added a place for Data Processing Options. Next, test the events in Meta Events Manager and compare the final consent copy with your legal team's requirements before you publish the change.

Newer article · 04Should You Build Your Own Cookie Banner? Build vs Buy GuideShould you build your own cookie banner or use a consent tool? Learn when custom cookie banners make sense, where they become consent infrastructure, and why c15t is a better default for modern JavaScript apps.Guides/9 min readOlder article · 06Privacy change management is the missing layer between shipping and compliancePrivacy work becomes operational when the unit of review is a product change—not a quarterly audit, spreadsheet, or policy refresh.Operating model/3 min read

Related

c15t Meta Pixel integration docsc15t Next.js quickstartc15t Next.js script loaderNext.js route change exampleMeta Pixel GDPR guidance

Notes from building privacy into the product

Notes from building Inth. Sent occasionally.

Inth connects what your company promised to what engineers just shipped.

Platform

  • Code audit
  • Website audit
  • Inth Agent
  • Consent banner
  • Pricing

Use Cases

  • Privacy Impact Review
  • AI Feature Reviews

Company

  • About
  • Blog
  • Open source
  • Contact

Resources

  • Documentation
  • GitHub
  • Cookiebench
  • Status

© 2026 Inth. All rights reserved.

  • Contact us
  • Privacy
  • Cookies
  • Terms