Search by

nowo-tech / marketing-kit-bundle

HecFranco

Symfony bundle to install and configure marketing tools (GTM, GA4, Meta Pixel, LinkedIn, TikTok, Hotjar, Clarity, custom) via YAML and/or Doctrine, with CookieConsent-compatible gating.

Package info

github.com/nowo-tech/MarketingKitBundle

Documentation

Type:symfony-bundle

pkg:composer/nowo-tech/marketing-kit-bundle

Statistics

Installs: 111

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.10.0 2026-11-11 02:05 UTC

README

CI Packagist Version Packagist Downloads License PHP Symfony GitHub stars Coverage

⭐ Found this useful? Give it a star on GitHub! It helps us maintain and improve the project.

Symfony marketing kit: install and configure GTM, GA4, Meta Pixel, LinkedIn Insight, TikTok Pixel, Hotjar, Microsoft Clarity, and custom snippets via YAML profiles and/or Doctrine, with CookieConsent-compatible category gating.

FrankenPHP Friendly Worker Mode

This bundle is FrankenPHP worker mode friendly, including kernel not reset between requests (see FrankenPHP worker audit).

Marketing services admin list with provider IDs, on/off state and row actions
Admin list — providers with IDs, on/off state and row actions
Marketing service edit form rejecting an invalid GA4 measurement ID
Edit form — provider options with ID format validation

Features

  • ✅ Providers (v1) — gtm, ga4, meta_pixel, linkedin, tiktok, hotjar, clarity, custom
  • ✅ YAML profiles — default_profile + profiles (REQ-CFG-001)
  • ✅ Database override — use_database_config: true replaces YAML tools when DB rows exist for the profile
  • ✅ Twig helpers — nowo_marketing_head(), nowo_marketing_body_start(), nowo_marketing_body_end()
  • ✅ CookieConsent-compatible — reads Cookie_Category_{analytics|marketing} (soft dependency)
  • ✅ Admin CRUD — /admin/marketing (web_ui.path_prefix) to configure services (seed catalog, import YAML, toggle, typed option fields, confirm before delete)
  • ✅ Admin security — security.access_roles (empty list denies) / custom access_checker, CSRF required, consent allowlist, optional CSP nonce; see Security (demo-only allow_unauthenticated)
  • ✅ Embeddable admin UI — UiKit page scaffolds (list + form): one host layout and theme (nowo_ui_kit.layouts.admin, css_framework, theme) for every Nowo bundle; see Templates

FrankenPHP: Demos use a single PHP service (FrankenPHP, no nginx). Runtime mode is controlled by FRANKENPHP_MODE in .env (worker default, or classic). The entrypoint selects Caddyfile (workers) or Caddyfile.dev (no workers) accordingly; see docs/DEMO-FRANKENPHP.md. Demo URL: http://localhost:8060 (see demo/README.md and .env.example).

Installation

composer require nowo-tech/marketing-kit-bundle
{# templates/base.html.twig #}
<head>
    {{ nowo_marketing_head() }}
</head>
<body>
    {{ nowo_marketing_body_start() }}
    {% block body %}{% endblock %}
    {{ nowo_marketing_body_end() }}
</body>

Optional GDPR gate (recommended):

composer require nowo-tech/cookie-consent-bundle

Requirements

  • PHP >= 8.2, < 8.6
  • Symfony >= 7.4 || >= 8.0
  • Doctrine ORM (for entities / optional DB config)
  • UiKitBundle ^2.15 (admin page scaffolds) and FormKitBundle ^2.10

Version information

Version PHP Symfony Status
1.3.x >= 8.2, < 8.6 7.4 – 8.x Stable
1.2.x >= 8.2, < 8.6 7.4 – 8.x Maintenance
1.1.x >= 8.2, < 8.6 7.4 – 8.x Maintenance
1.0.x >= 8.2, < 8.6 7.4 – 8.x Maintained

Quick configuration

# config/packages/nowo_marketing_kit.yaml
nowo_marketing_kit:
    use_database_config: false
    respect_cookie_consent: true
    security:
        access_roles: ['ROLE_ADMIN']
        allow_unauthenticated: false
    web_ui:
        enabled: true
        path_prefix: /admin/marketing
        layout_template: null   # null = nowo_ui_kit.layouts.admin
    default_profile: default
    profiles:
        default:
            enabled: true
            tools:
                gtm:
                    type: gtm
                    enabled: true
                    category: analytics
                    position: head
                    options:
                        container_id: '%env(default::GTM_ID)%'
                gtm_noscript:
                    type: gtm
                    enabled: true
                    category: analytics
                    position: body_start
                    options:
                        container_id: '%env(default::GTM_ID)%'
                meta_pixel:
                    type: meta_pixel
                    enabled: false
                    category: marketing
                    position: head
                    options:
                        pixel_id: '%env(default::META_PIXEL_ID)%'

Import admin routes when using the database admin:

# config/routes/nowo_marketing_kit.yaml
nowo_marketing_kit:
    resource: '@NowoMarketingKitBundle/Resources/config/routing.yaml'

Demos

make -C demo up-symfony8
# Demo started at: http://localhost:8060

Playwright e2e and README screenshots (REQ-DEMO-013; both reset the demo database first):

make -C demo/symfony8 test-e2e           # happy path of the admin (seed, import, edit, toggle, delete)
make -C demo/symfony8 demo-screenshots   # refresh docs/images/demo/*.webp

Documentation

Additional documentation

Tests and coverage

Language Lines (approx.) Command
PHP 100% make test-coverage
TypeScript N/A —
Python N/A —
composer test
composer test-coverage

License

The MIT License (MIT). Please see LICENSE for more information.