Facebook Pixel: Technical details
Facebook Pixel plugin for Shopware 6.7: flow from page request to Conversions API, plugin structure, subscribers and listener, template block, admin route of the connection test and plugin lifecycle.
Facebook Pixel: Technical details
Live Demo: Try this and other plugins live β no installation, no risk: demo.markus-michalski.net
Flow
graph TD
A["Storefront page is loaded"] --> B["Subscriber checks configuration"]
B -->|"tracking off or Pixel ID invalid"| C["nothing happens"]
B -->|"valid"| D["EventDataExtractor creates event with eventID"]
D --> E["PixelEventDispatched"]
D --> F["PixelJsRenderer creates fbq call"]
E --> G["CapiEventListener"]
G -->|"CAPI off, event not selected or no consent"| H["discarded"]
G -->|"all conditions met"| I["SendCapiEventMessage into queue"]
I --> J["SendCapiEventHandler"]
J --> K["ConversionsApiClient: graph.facebook.com"]
F --> L["Template base.html.twig"]
L -->|"consent missing (cookie check)"| M["no script"]
L -->|"consent present or Klaro"| N["script in the browser"]
Plugin structure
src/
βββ MmdFacebookPixel.php # Plugin class: activation, uninstall
βββ Capi/ # CAPI client, connection test, PiiHasher, server context
βββ Configuration/ # FacebookPixelConfig and factory (reads the system config)
βββ Controller/Admin/ # TestConnectionController
βββ Event/ # PixelEvent and the six event classes, PixelEventDispatched
βββ MessageQueue/ # SendCapiEventMessage and handler
βββ Migration/ # Create the Klaro service
βββ Renderer/ # PixelJsRenderer (creates the fbq calls)
βββ Service/ # ConsentChecker, EventDataExtractor, PixelCodeRenderer, KlaroServiceInstaller
βββ Struct/ # FacebookPixelStruct (page extension fbPixelEvent)
βββ Subscriber/ # Page subscribers and CapiEventListener
βββ Resources/ # config.xml, routes, services, snippets, template, admin component
Subscribers and listener
| Class | Listens to | Task |
|---|---|---|
StorefrontRenderSubscriber |
StorefrontRenderEvent |
Passes base code and PageView to the template, reports PageView for the CAPI |
ProductPageSubscriber |
ProductPageLoadedEvent |
ViewContent |
CategoryPageSubscriber |
NavigationPageLoadedEvent |
ViewCategory (loads the category via navigationId) |
CheckoutSubscriber |
CheckoutCartPageLoadedEvent, CheckoutConfirmPageLoadedEvent |
AddToCart (cart page), InitiateCheckout (confirmation page) |
OrderCompletedSubscriber |
CheckoutFinishPageLoadedEvent |
Purchase |
CapiEventListener |
PixelEventDispatched |
Checks the CAPI conditions, hashes email and phone, puts the message into the queue |
The page subscribers attach the tracking script to the page as the page extension fbPixelEvent. The template storefront/base.html.twig extends @Storefront/storefront/base.html.twig and outputs base code, PageView and the event script in the block base_body_script.
Extension points
PixelEventDispatchedis a regular Symfony event. Anyone who dispatches it with aPixelEventand aServerEventContextsends an event through the same CAPI conditions as the built-in ones.PixelEventRendererInterfaceandConversionsApiClientInterfaceare registered as interfaces.PixelJsRendererandConversionsApiClientsit behind them.
The classes are final. Create custom events by deriving your own class from PixelEvent rather than extending the existing ones.
Admin route of the connection test
| Property | Value |
|---|---|
| Method and path | POST /api/_action/mmd-facebook-pixel/test-connection |
| Route name | api.action.mmd_facebook_pixel.test_connection |
| Permission | system_config:read |
| Body (JSON) | pixelId, accessToken, optional testEventCode |
| Response (JSON) | success, httpStatus, messageKey, metaErrorMessage, metaErrorCode |
messageKey is one of success, missingPixelId, missingToken, invalidPixelId, metaError, networkError. The matching texts are in the admin snippets, see Configuration.
Plugin lifecycle
| When | Action |
|---|---|
| Install/update (migration) | Creates the Klaro service facebook-pixel if MmdKlaroConsent is installed |
| Activation | Creates the Klaro service if it is still missing and the Klaro table exists |
| Uninstall without "keep data" | Removes the Klaro service with its translations and all MmdFacebookPixel.config.* entries from system_config |
Further technical properties
- The Pixel ID is output as JSON with escaping of
<,>,&and quotes, and it must consist of digits only. - The configuration is read per sales channel from the system config. Switches that were never saved count as "On" (tracking options) or "Off" (master switch, consent, Conversions API).
- CAPI messages implement
AsyncMessageInterfaceand therefore run through the asynchronous transport. - Errors during delivery are logged and never thrown as exceptions.