Fixes · Meta pixel and tracking

Meta custom events not firing on Shopify

The fix

Your code runs before the pixel exists. The Facebook & Instagram app can load fbq a moment after a theme script checks for it once, so the event is dropped with no error.

Wait for the pixel: try again every 250 ms until fbq is there with a pixel set up, then send, and give up after a few seconds. Don’t make your own stand-in fbq to queue into.

01Why the event never leaves the page

A custom event is a call your own code makes, such as fbq('trackCustom', 'BookingComplete'). It works only once Meta’s pixel is on the page: Meta’s guide says the base code “must already be installed on every page where you want to track conversions” (Meta, Conversion tracking).

On many Shopify stores the base code isn’t in the theme at all. The Facebook & Instagram app adds the pixel, on its own schedule. On the store below it appeared about a tenth of a second after the theme’s tracking script had run: we measured the script at 992 ms and the pixel at 1,102 ms on the home page, and 848 ms against 956 ms on the contact page (21 Oct 2026). Code that checks typeof fbq === 'function' once finds nothing and skips the event. There’s no error, and the same line typed into the console a second later works.

That last part is what the owner on this thread (Mar 2025) saw: the code fired when run by hand in the console, not on its own. On another (Jun 2025), with the pixel from the app and no code of the owner’s own, expected events were missing; neither thread reached a fix.

Where your code runs decides which fbq it sees

  1. 01

    In the theme

    A script in the layout or a section shares the page with the pixel the app adds, and has to wait for it. The fix below is for this case.

  2. 02

    In Customer events (a custom pixel)

    Custom pixels run in a sandboxed iframe, and pixels placed there “cannot access the top frame” (Shopify, About web pixels). Load Meta’s base code inside the custom pixel and call fbq there. To trigger it from the theme, publish your own event with Shopify.analytics.publish('my_store:booking_complete', data) and subscribe to it in the pixel (Shopify, Emitting data).

  3. 03

    Through the app alone

    The owner on the 2025 thread reports that the app sends standard events only, with no setting for custom ones.

02Find where your code runs, then wait for the pixel

For store owners

  1. See what Meta receives

    In Meta Events Manager, open your pixel’s Test events, enter your store’s address, and do the thing that should send the event: send the form, finish the booking.

  2. Accept marketing cookies when you test

    On the store we fixed, the pixel never loaded for a visitor who declined them, which is as it should be.

  3. Standard events arrive and yours don’t?

    Send your developer this page: the code most likely checks for the pixel too early.

  4. Look in Customer events too

    Settings > Customer events lists custom pixels. If your custom event is set up there, it needs Meta’s code inside that pixel (the second case above).

For developers: wait for a pixel that’s set up, then send

One helper for every Meta call. It waits until fbq exists and has a pixel set up, trying every 250 ms, and gives up quietly after ten seconds. Here is the shape of what we shipped:

Send to Meta once the pixel is readyjs
const RETRY_MS = 250;
const GIVE_UP_MS = 10000;

// fbq exists AND has a pixel set up. getState() is what the pixel exposes;
// it isn't in Meta's documented reference, so every step is guarded.
function metaReady() {
  if (typeof window.fbq !== 'function') return false;
  try {
    const state = typeof window.fbq.getState === 'function' ? window.fbq.getState() : null;
    return Boolean(state && state.pixels && state.pixels.length);
  } catch (e) {
    return false;
  }
}

function sendMeta(kind, name, eventId) {
  const started = Date.now();
  (function attempt() {
    if (metaReady()) {
      try {
        if (eventId) window.fbq(kind, name, {}, { eventID: String(eventId) });
        else window.fbq(kind, name);
      } catch (e) { /* never break the page */ }
      return;
    }
    if (Date.now() - started >= GIVE_UP_MS) return; // no pixel: no consent, or blocked
    setTimeout(attempt, RETRY_MS);
  })();
}

sendMeta('trackCustom', 'BookingComplete', bookingId);
  • Wait for a pixel in getState().pixels, not only for fbq, so the event can’t land before the pixel is set up.
  • Don’t create a stand-in fbq to queue calls. Meta’s base code begins if(f.fbq)return; (Meta, Get started), so when fbq already exists it doesn’t load at all.
  • Pass an event ID if the same event can also reach Meta from a server. Meta recommends eventID as the fourth argument for deduplication (Meta, Pixel reference).
  • Send once. If the event fires on a thank-you page, keep a flag per visit (we use sessionStorage) so a reload doesn’t count it again.
  • Giving up is right. Without marketing consent there’s no pixel, and the helper sends nothing.
  • If typeof fbq is still 'undefined' in the console once the page has loaded and you’ve accepted cookies, the pixel isn’t on the page itself, and waiting won’t help. Send the event from a custom pixel instead (the second case above).

03Watch one request go out

  1. Block Meta, then watch

    In developer tools, block requests to facebook.com/tr, accept marketing cookies and do the action. The Network tab should show exactly one blocked request with your event name (ev=) and, if you send one, your event ID (eid=). Blocking keeps tests out of your reports.

  2. Try with an empty cache

    The race is closest when nothing is cached.

  3. Decline cookies

    Nothing should be sent, and nothing on the page should break.

  4. Then confirm in Events Manager

    Unblock, and test once more with Test events open.

From our work

04Bookings and enquiries on a wellness brand’s site

On a site we built for a wellness brand, enquiries and bookings go through an outside booking system, and the site sends Meta its own custom events when one completes. The pixel comes from the Facebook & Instagram app; the site’s tag manager has no Meta tags.

Before. The tracking script checked for fbq once. The pixel arrived about a tenth of a second later, so the enquiry event went nowhere, and the store’s team saw custom events stop arriving in Meta. Meta’s standard Schedule event had a problem of its own: the booking system sent it when its booking page opened, before anything was booked.

After (21 Oct 2026). Every Meta call goes through one helper that waits for the pixel, as above, and the site now sends Schedule itself from the booking-confirmed page, once per visit. Proven on the live site the same day: one request with the event and its ID, and nothing sent with cookies declined.

  • In our live log“Booking and marketing tracking now waits for the tracking tool to be ready”

The bigger picture

05Tracking that fails quietly

Tracking that fails quietly looks like a bad month for your ads. If your numbers dropped with no reason you can find, or custom events come and go, check what actually reaches Meta before you change the campaigns.

06Sources

Every step and claim above comes from one of these, or from the fix on the store it describes.

  1. Meta for Developers: Conversion tracking (standard and custom events)
  2. Meta for Developers: Meta Pixel reference
  3. Meta for Developers: Get started (the base code)
  4. Shopify developers: About web pixels (sandboxes)
  5. Shopify developers: Web pixels API, emitting data
  6. Shopify Community: Shopify won’t fire a customer event for custom event pixels to Meta (Mar 2025)
  7. Shopify Community: Meta events are not tracking (Jun 2025)

Sources checked on .

Contact

Events missing in Meta?

Tell us which events you expect, and where your pixel comes from.