Why I’m building MockShop, the stack behind it, and how to run it locally or with Docker to validate GA4/Matomo/ODP/Optimizely implementations.

Note: MockShop has been renamed to shop404. Names and examples below may still refer to MockShop while I update docs.

Most analytics and experimentation work happens on real sites with real constraints. That’s great for context—but not so great when you need a safe, repeatable environment to design data models, validate tagging, or run parity checks across tools.

Enter MockShop: my in‑progress, private demo store that combines a simple ecommerce flow and a multi‑step donation wizard. It’s designed to exercise “just enough” complexity to hit real‑world cases without dragging you into framework internals or complicated backends.

Status: private, WIP (not yet released). If you’re curious or want early access, reach out.

Why I’m building this

  • Repeatable QA: Stand up a clean, consistent environment for analytics and tag manager validation.
  • Parity testing: Compare GA4 and Matomo side‑by‑side using the same events and journeys.
  • Consent‑aware demos: Show how Consent Mode (GTM) and _paq.requireConsent (Matomo) shape data collection.
  • Experimentation scaffolding: Drop in Optimizely Web snippets to prototype activations and measure impact.
  • Teaching tool: A concrete playground for workshops and onboarding analysts/engineers.

What’s inside

  • Ecommerce flow: products grid → product details → cart → checkout → order confirmation.
  • Donation wizard (SPA): amount → details → payment → review → success.
    • Monthly vs one‑time nudge; optional persistent monthly default stored per device.
    • Client‑side validation with donation_step error markers (great for funnels).
  • Analytics helpers: unified pushes to window.dataLayer (GA4/GTM) and window._mtm (Matomo Tag Manager).
    • GA4 ecommerce item structure with category hierarchy (item_category..item_category5).
    • List context for impressions (item_list_name, item_list_id, items[].index).
    • Currency/purchase mapping; optional tax/shipping.
  • Matomo Content Tracking on the Learn/Resources section:
    • Automatic impressions + visible impressions, explicit interaction events on CTAs/teasers.
    • SPA safety with trackContentImpressionsWithinNode(document).
  • Consent banner with categories (analytics, marketing, experimentation).
    • GTM always loads; Consent Mode v2 governs behavior.
    • Matomo uses _paq.requireConsent and consent events from _mtm.
  • Runtime config via /config.json: injects GTM ID, MTM container URL, Optimizely Web snippet, and ODP SDK URL.

Stack & approach

  • Frontend: Vite + React + Tailwind (fast dev loop, clear component boundaries, minimal ceremony).
  • No backend database: It’s a mock—so everything you need for analytics is client‑side, and runtime configuration comes from /config.json.
  • Docker‑first deploy: The production image serves static assets and a tiny runtime that emits /config.json from environment variables.
  • Indexing locked down by default: robots and meta tags block crawlers in demo builds.

Key events & data layer MockShop emits a focused set of events you’d expect from a modern shop and a donation flow:

  • page_view: on route changes/pages.
  • view_item_list: impressions with item_list_name, item_list_id, and per‑item index.
  • view_item: product detail.
  • add_to_cart: add to cart (always include ecommerce.currency).
  • begin_checkout: checkout start (with ecommerce.currency).
  • purchase: order confirmation (includes transaction_id, value, currency, optional tax/shipping).
  • donation_step: donation wizard step with metadata (e.g., step, optional amount, interval, error).

GA4 mapping notes

  • Items use GA4 naming (item_id, item_name, price, quantity, item_category..item_category5).
  • Impressions include list context (item_list_name, item_list_id, index).
  • Currency is included on cart/checkout/purchase.
  • For funnels, donation steps annotate errors and context.

Matomo mapping notes

  • Tag via Matomo Tag Manager and consume the same ecommerce object and custom events from _mtm.
  • Parity: GA4’s single‑item add_to_cart vs Matomo’s update_cart (FULL CART). MockShop emits update_cart on add/remove/quantity change and again at begin_checkout.
  • Content tracking: blocks marked with matomoTrackContent and data-content-* attributes; SPA pages trigger scans explicitly.

Consent behavior

  • GTM: Consent Mode v2 defaults are denied; user choice updates the model. GTM still loads but honors consent.
  • Matomo: _paq.requireConsent is queued; consent events from the banner drive allow/deny behavior. MTM triggers can key off _mtm consent events.

Local development Prereqs: Node 18+.

  1. Install and run
npm install
npm run dev
# App serves at http://localhost:5173
  1. Configure tags in dev
  • Edit public/config.json to set GTM_ID, MATOMO_TAG_MANAGER_CONTAINER_URL, and optional Optimizely/ODP URLs.
  • Do not commit secrets—public/config.json in dev is your scratchpad.
  1. Build/preview
npm run build
npm run preview

Docker (local build)

docker build -t mockshop .
docker run -p 8080:3000 \
  -e GTM_ID=GTM-XXXXXXX \
  -e MATOMO_TAG_MANAGER_CONTAINER_URL=https://matomo.example.com/js/container_ABC123.js \
  -e OPTIMIZELY_WEB_SNIPPET_URL=https://cdn.optimizely.com/js/PROJECT_ID.js \
  -e ODP_SDK_URL=https://cdn.foqt.com/v1/odp.js \
  mockshop

# App is at http://localhost:8080, and /config.json reflects env vars

Quick tips for credible testing

  • Use small, realistic volumes; you’re validating logic, not load‑testing.
  • Keep transaction_id unique on purchases; include currency consistently.
  • For impressions, always include list context; for category hierarchies, prefer a path array you can map to GA4 fields and Matomo variables.
  • For consent, test both “analytics on” and “analytics off” paths and verify behavior in GTM Preview and MTM Preview.

Roadmap highlights (WIP)

  • Test harness to snapshot emitted payloads and compare against expectations (GA4 & Matomo parity checks).
  • Optional Optimizely variations to demo activation patterns (URL, audience, attributes).
  • Lightweight sample catalog tweaks to cover variant/option cases.

Current status & access MockShop is a private repo while I round off edges and docs. I’ll publish when it’s stable and properly documented. If you’d like early access for analytics QA or training work, ping me.