Installing Meta Pixel on Storyblok with Nuxt and Next.js | OpsBlu Docs

Installing Meta Pixel on Storyblok with Nuxt and Next.js

Complete guide to setting up Meta (Facebook) Pixel tracking on Storyblok-powered sites for conversion tracking and remarketing

Meta Pixel (formerly Facebook Pixel) enables conversion tracking, audience building, and remarketing for Storyblok-powered websites. This guide covers implementation for Nuxt.js, Next.js, and custom implementations.


Prerequisites

Before you begin:

  • Have a Meta Pixel ID from Facebook Business Manager
  • Have a Storyblok space set up
  • Be using Nuxt.js, Next.js, or another JavaScript framework
  • Have Facebook Business Manager access

Get Your Meta Pixel ID

  1. Log in to Facebook Business Manager
  2. Navigate to Events Manager
  3. Click Connect Data Sources > Web
  4. Select Meta Pixel
  5. Copy your Pixel ID (format: 16-digit number)

Method 1: Nuxt.js with Storyblok

Step 1: Install Facebook Pixel Module

npm install @nuxtjs/facebook-pixel

Step 2: Configure nuxt.config.ts

// nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@storyblok/nuxt',
    '@nuxtjs/facebook-pixel',
  ],

  storyblok: {
    accessToken: process.env.STORYBLOK_TOKEN,
  },

  facebookPixel: {
    pixelId: process.env.NUXT_PUBLIC_META_PIXEL_ID,
    track: 'PageView',
    version: '2.0',
    disabled: process.env.NODE_ENV !== 'production',
  },

  runtimeConfig: {
    public: {
      metaPixelId: process.env.NUXT_PUBLIC_META_PIXEL_ID,
    },
  },
});

Step 3: Create Meta Pixel Plugin (Manual Alternative)

If not using module, create plugins/meta-pixel.client.ts:

// plugins/meta-pixel.client.ts
export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig();
  const pixelId = config.public.metaPixelId;

  if (!pixelId) {
    console.warn('Meta Pixel ID not found');
    return;
  }

  // Load Meta Pixel
  !(function(f:any,b,e,v,n:any,t,s) {
    if(f.fbq)return;n=f.fbq=function(){n.callMethod?
    n.callMethod.apply(n,arguments):n.queue.push(arguments)};
    if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
    n.queue=[];t=b.createElement(e);t.async=!0;
    t.src=v;s=b.getElementsByTagName(e)[0];
    s.parentNode.insertBefore(t,s)
  })(window, document,'script',
  'https://connect.facebook.net/en_US/fbevents.js');

  window.fbq('init', pixelId);
  window.fbq('track', 'PageView');

  // Track route changes
  const router = useRouter();
  router.afterEach(() => {
    window.fbq('track', 'PageView');
  });
});

Step 4: Environment Variables

Create .env:

STORYBLOK_TOKEN=your-storyblok-token
NUXT_PUBLIC_META_PIXEL_ID=1234567890123456

Method 2: Next.js with Storyblok

Step 1: Create Meta Pixel Component

Create components/MetaPixel.js:

'use client';

import Script from 'next/script';
import { useEffect } from 'react';
import { usePathname, useSearchParams } from 'next/navigation';

export default function MetaPixel({ pixelId }) {
  const pathname = usePathname();
  const searchParams = useSearchParams();

  useEffect(() => {
    if (typeof window.fbq !== 'undefined') {
      window.fbq('track', 'PageView');
    }
  }, [pathname, searchParams]);

  return (
    <>
      <Script id="meta-pixel" strategy="afterInteractive">
        {`
          !function(f,b,e,v,n,t,s)
          {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
          n.callMethod.apply(n,arguments):n.queue.push(arguments)};
          if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
          n.queue=[];t=b.createElement(e);t.async=!0;
          t.src=v;s=b.getElementsByTagName(e)[0];
          s.parentNode.insertBefore(t,s)}(window, document,'script',
          'https://connect.facebook.net/en_US/fbevents.js');
          fbq('init', '${pixelId}');
          fbq('track', 'PageView');
        `}
      </Script>
      <noscript>
        <img
          height="1"
          width="1"
          style={{ display: 'none' }}
          src={`https://www.facebook.com/tr?id=${pixelId}&ev=PageView&noscript=1`}
          alt=""
        />
      </noscript>
    </>
  );
}

Step 2: Add to Root Layout

// app/layout.js
import { storyblokInit, apiPlugin } from '@storyblok/react';
import MetaPixel from '@/components/MetaPixel';

storyblokInit({
  accessToken: process.env.NEXT_PUBLIC_STORYBLOK_TOKEN,
  use: [apiPlugin],
});

const META_PIXEL_ID = process.env.NEXT_PUBLIC_META_PIXEL_ID;

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <head>
        {META_PIXEL_ID && <MetaPixel pixelId={META_PIXEL_ID} />}
      </head>
      <body>{children}</body>
    </html>
  );
}

Storyblok-Specific Tracking

Track Component Interactions

<!-- components/CallToActionButton.vue (Nuxt 3) -->
<template>
  <button @click="handleClick" v-editable="blok">
    {{ blok.text }}
  </button>
</template>

<script setup>
const { blok } = defineProps(['blok']);

const handleClick = () => {
  if (typeof window.fbq === 'function') {
    window.fbq('track', 'Lead', {
      content_name: blok.text,
      content_category: 'CTA Button',
      component_type: blok.component,
    });
  }
};
</script>

Track Form Submissions

<!-- components/ContactForm.vue (Nuxt 3) -->
<template>
  <form @submit.prevent="handleSubmit" v-editable="blok">
    <input v-model="email" type="email" required />
    <button type="submit">Submit</button>
  </form>
</template>

<script setup>
const { blok } = defineProps(['blok']);
const email = ref('');

const handleSubmit = async () => {
  if (typeof window.fbq === 'function') {
    window.fbq('track', 'Contact', {
      content_name: blok.form_title,
      component_type: blok.component,
    });
  }

  // Submit form
};
</script>

Track Story Views by Type

<!-- pages/[...slug].vue (Nuxt 3) -->
<script setup>
const { slug } = useRoute().params;
const story = await useAsyncStoryblok(slug.join('/'));

onMounted(() => {
  if (story.value && typeof window.fbq === 'function') {
    window.fbq('track', 'ViewContent', {
      content_ids: [story.value.id],
      content_type: story.value.content.component,
      content_name: story.value.name,
    });
  }
});
</script>

Standard Meta Pixel Events

Purchase Event

function handlePurchase(order) {
  if (typeof window.fbq === 'function') {
    window.fbq('track', 'Purchase', {
      value: order.total,
      currency: 'USD',
      content_ids: order.items.map(item => item.id),
      content_type: 'product',
    });
  }
}

Add to Cart Event

function handleAddToCart(product) {
  if (typeof window.fbq === 'function') {
    window.fbq('track', 'AddToCart', {
      value: product.price,
      currency: 'USD',
      content_ids: [product.id],
      content_name: product.name,
      content_type: 'product',
    });
  }
}

Testing & Validation

1. Meta Pixel Helper

  1. Install Meta Pixel Helper
  2. Visit your Storyblok site
  3. Click extension icon
  4. Verify Pixel is detected and events fire

2. Events Manager Test Events

  1. Go to Events Manager > Test Events
  2. Enter your browser identifier or IP
  3. Interact with your site
  4. See events appear in real-time

Privacy & Compliance

// composables/useConsentAwarePixel.ts
export const useConsentAwarePixel = () => {
  const hasConsent = ref(false);

  onMounted(() => {
    // Check consent (use your consent management platform)
    hasConsent.value = localStorage.getItem('cookie-consent') === 'true';
  });

  const trackEvent = (eventName: string, params: any) => {
    if (hasConsent.value && typeof window.fbq === 'function') {
      window.fbq('track', eventName, params);
    }
  };

  return { trackEvent, hasConsent };
};

Next Steps


Additional Resources