The most powerful and developer-friendly Meta Pixel integration for Nuxt 3 & 4.
Built on top of @adkit.so/meta-pixel, this module provides a seamless, type-safe Meta Pixel experience with advanced features like route control, event deduplication, and beautiful debug logging.
- Features
- Quick Start
- Installation
- Configuration
- Usage
- Route Control
- Standard Events
- Advanced Usage
- Troubleshooting
- Official Documentation
- License
- β Typescript Support - Full TypeScript support with autocomplete for all official events and parameters
- π¨ Auto-imported Composable -
useMetaPixel()available everywhere, zero boilerplate - π― Custom Events Support - Track custom events with full type safety and flexible data structures
- π£οΈ Advanced Route Control - Granular control on where to enable or disable tracking
- π¦ Event Deduplication - Support for preventing duplicate events with event IDs
- π Multiple Pixels Support - Load and manage multiple pixel IDs effortlessly
npx nuxi@latest module add @adkit.so/meta-pixel-nuxtOR
npm install @adkit.so/meta-pixel-nuxtexport default defineNuxtConfig({
modules: ['@adkit.so/meta-pixel-nuxt'],
metaPixel: {
pixelIds: 'YOUR_PIXEL_ID',
},
});<template>
<button @click="handlePurchase">Complete Purchase</button>
</template>
<script setup>
const meta = useMetaPixel();
const handlePurchase = () => {
meta.track('Purchase', {
value: 99.99,
currency: 'USD',
});
};
</script>That's it! π
npx nuxi@latest module add @adkit.so/meta-pixel-nuxtnpm install @adkit.so/meta-pixel-nuxtAdd the module to your nuxt.config.ts:
export default defineNuxtConfig({
modules: ['@adkit.so/meta-pixel-nuxt'],
metaPixel: {
pixelIds: 'YOUR_PIXEL_ID', // or array ['PIXEL_1', 'PIXEL_2']
autoTrackPageView: true, // default: true
debug: true, // Enable debug logs (default: false)
enableLocalhost: true, // Enable on localhost (default: false)
},
});| Option | Type | Default | Description |
|---|---|---|---|
pixelIds |
string | string[] |
'' |
Required. Single pixel ID or array of pixel IDs |
autoTrackPageView |
boolean |
true |
Automatically track PageView on initialization |
debug |
boolean |
false |
Enable styled console logs with background colors |
enableLocalhost |
boolean |
false |
Enable tracking on localhost (useful for testing) |
excludedRoutes |
string[] |
[] |
Array of glob patterns to exclude from tracking (e.g., /dashboard/**) |
includedRoutes |
string[] |
[] |
Array of glob patterns to whitelist (only these routes will be tracked) |
// nuxt.config.ts
export default defineNuxtConfig({
metaPixel: {
pixelIds: ['PIXEL_ID_1', 'PIXEL_ID_2', 'PIXEL_ID_3'],
autoTrackPageView: true,
},
});The useMetaPixel() composable is auto-imported and ready to use anywhere in your Nuxt app. It provides direct access to the Meta Pixel instance with all methods from @adkit.so/meta-pixel.
<!-- index.vue -->
<template>
<button @click="meta.track('AddToCart', { value: 29.99, currency: 'USD' })">Add to Cart</button>
</template>
<script setup>
const meta = useMetaPixel();
// Track standard events
meta.track('Purchase', {
value: 99.99,
currency: 'USD',
content_ids: ['SKU_123'],
});
// Track custom events
meta.trackCustom('MyCustomEvent', {
custom_param: 'value',
});
</script><!-- index.vue -->
<template>
<button @click="handleCheckout">Checkout</button>
</template>
<script setup>
const meta = useMetaPixel();
const handleCheckout = () => {
meta.track(
'InitiateCheckout',
{
value: 149.99,
currency: 'USD',
num_items: 3,
},
{
eventID: `checkout-${Date.now()}`,
},
);
};
</script><!-- index.vue -->
<template>
<button @click="trackIfReady">Track Purchase</button>
</template>
<script setup>
const meta = useMetaPixel();
const trackIfReady = () => {
if (meta.isLoaded()) {
meta.track('Purchase', { value: 99.99, currency: 'USD' });
}
};
</script>You can control where the pixel is loaded using three methods:
In nuxt.config.ts, provide an array of glob patterns to exclude specific routes:
// nuxt.config.ts
export default defineNuxtConfig({
metaPixel: {
pixelIds: '...',
excludedRoutes: [
'/dashboard/*', // Excludes /dashboard/inbox, /dashboard/settings (one level)
'/dashboard/**', // Excludes /dashboard and ALL nested routes (any depth)
'/admin/**', // Excludes /admin and all nested routes
'/api/*', // Excludes /api/users, /api/posts (one level only)
],
},
});Pattern Syntax:
*- Matches any characters except/(single path segment)**- Matches any characters including/(multiple path segments, any depth)
Examples:
/dashboard/*β Excludes/dashboard/inboxbut NOT/dashboard/inbox/messages/dashboard/**β Excludes/dashboard,/dashboard/inbox,/dashboard/inbox/messages, etc. (any depth)/api/*β Excludes/api/usersbut NOT/api/users/123
If you only want to track specific sections, use includedRoutes. This takes precedence over excluded routes (except for page-level overrides).
// nuxt.config.ts
export default defineNuxtConfig({
metaPixel: {
pixelIds: '...',
includedRoutes: [
'/shop/**', // Track all shop pages (any depth)
'/checkout/**', // Track all checkout pages (any depth)
'/product/*', // Track product pages (one level only)
],
},
});You can enable or disable the pixel on a per-page basis using definePageMeta:
<template>
<div>Secret page - no tracking here</div>
</template>
<script setup>
definePageMeta({
metaPixel: false,
});
</script>Priority Order:
- Page-level
definePageMeta(highest priority) includedRoutes(if set, only these are tracked)excludedRoutes(if set, these are ignored)- Default: Track everything
You can configure pixel IDs via environment variables instead of hardcoding them in nuxt.config.ts. This is especially useful for different environments (dev, staging, production).
# .env
META_PIXEL_ID=123456789012345Then reference it in your config:
// nuxt.config.ts
export default defineNuxtConfig({
metaPixel: {
pixelIds: process.env.META_PIXEL_ID || '',
},
});# .env
META_PIXEL_DEFAULT=123456789012345
META_PIXEL_BACKUP=987654321098765export default defineNuxtConfig({
metaPixel: {
pixelIds: [process.env.META_PIXEL_DEFAULT, process.env.META_PIXEL_BACKUP],
},
});When debug: true, you'll see beautiful styled console logs:
- π΅ [Meta Pixel] Info messages (blue background)
- β [Meta Pixel] Success messages (green background)
β οΈ [Meta Pixel] Warning messages (orange background)
Example output:
[Meta Pixel] Initializing Meta Pixel... { pixelIds: [...], autoTrackPageView: true }
[Meta Pixel] β Meta Pixel initialized successfully
[Meta Pixel] Tracking standard event: "Purchase" { data: {...}, eventData: {...} }
All Meta Pixel standard events are supported with full TypeScript autocomplete. These events help you track important actions on your website and optimize your ad campaigns.
| Event | Description | Common Use Cases |
|---|---|---|
AddPaymentInfo |
Payment info added | Checkout flow |
AddToCart |
Item added to shopping cart | E-commerce |
AddToWishlist |
Item added to wishlist | E-commerce |
CompleteRegistration |
User completed registration | Sign-ups, account creation |
Contact |
User contacted business | Contact forms |
CustomizeProduct |
Product customization started | Product configurators |
Donate |
Donation made | Non-profits |
FindLocation |
Location finder used | Store locators |
InitiateCheckout |
Checkout process started | E-commerce funnels |
Lead |
Lead submitted | Lead generation forms |
Purchase |
Purchase completed | Transaction confirmation |
Schedule |
Appointment scheduled | Booking systems |
Search |
Search performed | Site search |
StartTrial |
Trial started | SaaS applications |
SubmitApplication |
Application submitted | Job boards, loan applications |
Subscribe |
Subscription started | Newsletters, subscriptions |
ViewContent |
Content viewed | Product pages, blog posts |
You can find the official list of standard events here.
<template>
<div>
<button @click="trackPurchase">Complete Purchase</button>
<button @click="trackLead">Submit Lead</button>
<input @input="trackSearch($event.target.value)" placeholder="Search..." />
</div>
</template>
<script setup>
const meta = useMetaPixel();
const trackPurchase = () => {
meta.track('Purchase', {
value: 299.99,
currency: 'USD',
content_ids: ['SKU_12345'],
content_type: 'product',
num_items: 1,
});
};
const trackLead = () => {
meta.track('Lead', {
content_name: 'Newsletter Signup',
content_category: 'Marketing',
});
};
const trackSearch = (query: string) => {
meta.track('Search', {
search_string: query,
});
};
</script>All event parameters are optional but help improve ad targeting and conversion tracking. Here are the most common ones:
| Parameter | Type | Description | Example |
|---|---|---|---|
value |
number |
Monetary value of the event | 99.99 |
currency |
string |
ISO 4217 currency code | 'USD', 'EUR', 'GBP' |
content_ids |
string[] |
Product IDs or SKUs | ['SKU_123', 'SKU_456'] |
content_type |
string |
Type of content | 'product', 'product_group' |
content_name |
string |
Name of page/product | 'Blue T-Shirt' |
content_category |
string |
Category of page/product | 'Apparel', 'Electronics' |
contents |
Array<{id, quantity}> |
Detailed product information | [{id: 'SKU_123', quantity: 2}] |
num_items |
number |
Number of items | 3 |
search_string |
string |
Search query | 'running shoes' |
status |
boolean |
Registration/subscription status | true |
predicted_ltv |
number |
Predicted lifetime value of customer | 450.00 |
<template>
<div>
<h1>{{ product.name }}</h1>
<p>${{ product.price }}</p>
<button @click="trackAddToCart">Add to Cart</button>
<button @click="trackPurchase('order-123')">Buy Now</button>
</div>
</template>
<script setup>
const meta = useMetaPixel();
const product = {
id: 'SKU_789',
name: 'Wireless Headphones',
price: 149.99,
category: 'Electronics',
};
onMounted(() => {
trackProductView();
});
const trackProductView = () => {
meta.track('ViewContent', {
content_ids: [product.id],
content_type: 'product',
content_name: product.name,
content_category: product.category,
value: product.price,
currency: 'USD',
});
};
const trackAddToCart = () => {
meta.track('AddToCart', {
content_ids: [product.id],
content_type: 'product',
content_name: product.name,
value: product.price,
currency: 'USD',
});
};
const trackPurchase = (orderId: string) => {
meta.track(
'Purchase',
{
content_ids: [product.id],
content_type: 'product',
value: product.price,
currency: 'USD',
num_items: 1,
},
{
eventID: orderId,
},
);
};
</script>Track custom events specific to your business:
<template>
<div>
<button @click="trackPricingView">View Pricing</button>
<video @ended="trackVideoComplete">Your video</video>
</div>
</template>
<script setup>
const meta = useMetaPixel();
const trackPricingView = () => {
meta.trackCustom('PricingPageViewed', {
plan: 'enterprise',
duration: 'annual',
});
};
const trackVideoComplete = () => {
meta.trackCustom('VideoWatched', {
video_id: 'intro_2024',
watch_percentage: 100,
});
};
</script>Prevent duplicate event tracking by using unique event IDs. This is crucial when tracking conversions from both client and server:
<script setup>
const meta = useMetaPixel();
const processOrder = async (orderId: string) => {
// Use order ID as event ID to prevent duplicates
meta.track(
'Purchase',
{
value: 299.99,
currency: 'USD',
content_ids: ['SKU_123'],
},
{
eventID: `order-${orderId}`,
},
);
// Even if this fires multiple times or from server too,
// Meta will deduplicate based on eventID
};
</script><script setup>
const meta = useMetaPixel();
const userStore = useUserStore();
const trackWithUserContext = () => {
// Only track if pixel is loaded
if (!meta.isLoaded()) {
console.warn('Meta Pixel not loaded yet');
return;
}
// Add user context to events
meta.track('CompleteRegistration', {
status: true,
content_name: userStore.accountType,
});
};
</script>Full type safety with exported types:
import type { StandardEvent, EventData, EventMetaData } from '@adkit.so/meta-pixel';
const meta = useMetaPixel();
const trackEvent = (event: StandardEvent, data: EventData) => {
meta.track(event, data);
};All methods, events, and parameters have complete TypeScript definitions with IntelliSense support in your IDE.
- Check your pixel ID - Make sure it's correct in your config
- Enable debug mode - Set
debug: trueto see detailed logs - Check browser console - Look for errors or warnings
- Verify route isn't excluded - Check your
excludedRoutesconfig - Enable on localhost - Set
enableLocalhost: truefor local testing
If your routes aren't being excluded properly:
-
Use glob patterns - For most cases, glob patterns are easier:
excludedRoutes: ['/dashboard/**']; // β Correct - excludes all dashboard routes
-
Common mistakes to avoid:
// β Wrong - missing leading slash excludedRoutes: ['dashboard/**']; // β Correct - with leading slash excludedRoutes: ['/dashboard/**'];
-
Enable debug mode to see which routes are being excluded:
metaPixel: { debug: true, // Will log "Route excluded: /dashboard/inbox" excludedRoutes: ['/dashboard/**'], }
-
Pattern examples:
/dashboard/*- Excludes/dashboard/inboxbut NOT/dashboard/inbox/messages/dashboard/**- Excludes/dashboard,/dashboard/inbox,/dashboard/inbox/messages, etc. (any depth)
- Wait a few minutes - Events can take 5-20 minutes to appear
- Check Test Events - Use the Test Events tool in Meta Events Manager
- Verify event names - Standard events are case-sensitive
- Use event deduplication - Add unique
eventIDto prevent duplicates - Check ad blockers - Some extensions block Meta Pixel
Make sure you have the latest version:
npm update @adkit.so/meta-pixel-nuxt// β
Correct
metaPixel: {
pixelIds: ['ID_1', 'ID_2'],
}
// β Incorrect
metaPixel: {
pixelIds: 'ID_1,ID_2',
}For a complete step-by-step guide on installing and configuring Meta Pixel, check out our detailed tutorial:
Learn more about Meta Pixel from official Facebook resources:
- Meta Pixel Reference - Complete API reference
- Standard Events Guide - Detailed event documentation
- Object Properties Reference - All available event parameters
- Conversions API - Server-side event tracking
- Events Manager - Monitor your pixel events
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
MIT
Made with β€οΈ by Adkit
If this package helped you, please consider giving it a βοΈ on GitHub!