Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Plausible Analytics Bundle Laravel Package

toovalu/plausible-analytics-bundle

Symfony bundle for integrating Plausible Analytics, the lightweight, privacy-friendly web analytics tool. Configure your domain, inject the tracking script, and optionally track custom events without cookies or consent banners.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Check the framework fit first. This is a Symfony bundle (...Bundle), not a Laravel package. It registers a Bundle class and ships Symfony DI config. You cannot composer require it into a Laravel app and expect it to work out of the box — treat this assessment as "what it does and how to mirror it" unless you're actually on Symfony. If you are on Laravel, the practical path is to read this bundle's source (it's small) and replicate the two things that matter: the front-end script tag and the server-side event POST.
  • Install (Symfony): composer require toovalu/plausible-analytics-bundle, then let Flex register it in config/bundles.php (or add Toovalu\PlausibleAnalyticsBundle\PlausibleAnalyticsBundle::class => ['all' => true] manually).
  • Configure first: look in config/packages/ for the bundle's config tree (usually plausible_analytics:). The three values you almost always need are domain (the data-domain you registered in Plausible), API key (for the events API, not the front-end script), and base URL (only set this if you self-host Plausible; default is https://plausible.io).
  • First use case — pageviews via the front-end script: in your base Twig layout {% block head %}, render the bundle's Twig helper/extension that emits Plausible's <script defer data-domain="…" src="…/js/script.js">. This is the 90% path and requires no API key.
  • Second use case — a server-side event: inject the bundle's event/client service into a controller and call something like ->track('Signup', ['plan' => 'pro']). This hits Plausible's /api/event endpoint and needs the API key + the User-Agent/X-Forwarded-For of the end user.
  • Where to look in the repo: Resources/config/services.xml (what services are actually public/available), the DependencyInjection/Configuration.php (exact config keys — this is your source of truth, the README may lag), and the Twig extension class if one exists.

Implementation Patterns

  • Layout-level script injection. Add the Twig helper once in your <head>. Keep data-domain in config, not hardcoded, so staging and prod point at different Plausible sites (or staging points at nothing).
  • Server-side goal tracking in controllers. Wrap the client service in your own thin Analytics service so your controllers depend on your interface, not the vendor bundle. This makes it trivial to swap in a NullAnalytics for tests and to add context (user id, plan) consistently.
  • Track meaningful goals, not everything. Plausible bills/aggregates by event name; keep names stable and enumerated (Signup, Upgrade, Export). Pass arbitrary props as the second argument — Plausible stores them as custom properties.
  • API/JSON endpoints and non-JS clients. When a request won't execute the browser script (mobile app hitting your API, webhook, CLI), fire a server-side pageview or custom event. Remember to forward the end-user's User-Agent and X-Forwarded-For — Plausible uses them for device/geo attribution and will reject/under-attribute requests without them.
  • Self-hosted instances. Set the base URL in config once; both the script URL and the event API endpoint should derive from it. Double-check that the bundle doesn't hardcode plausible.io in the event client — if it does, decorate/override it.
  • Testing. In a Symfony functional test, replace the bundle's client service with a mock HTTP client (Symfony's MockHttpClient is ideal) and assert the POST body contains name, url, domain, and props. Don't let tests hit plausible.io.
  • Laravel mirror (if you're porting): implement an Analytics class using Http::withHeaders(['User-Agent' => …, 'X-Forwarded-For' => …])->post('https://plausible.io/api/event', [...]), bind it as a singleton, and put the script in resources/views/layouts/app.blade.php guarded by @production.

Gotchas and Tips

  • Framework mismatch is the #1 gotcha. "Bundle" means Symfony. On Laravel, Composer will pull it, but nothing auto-discovers or wires it, and its service definitions expect Symfony's container. Budget an hour to read the source and reimplement rather than trying to shoehorn it in.
  • Two different "keys." The front-end script needs no key. The events API needs a Bearer API key created in your Plausible site settings. Mixing these up is the most common 401.
  • Events API returns 202 Accepted, not 200. A "successful" call may look empty. Don't treat any non-2xx as silently OK, but also don't parse a body you won't get. Log the status code and, where available, the error message — Plausible returns useful 400 reasons (missing domain, missing name).
  • domain must match the site in Plausible exactly. Subdomain vs apex matters. A mismatch means events are accepted but land nowhere visible.
  • Ad blockers. The front-end script is blocked by most blockers (Plausible is less targeted than GA but still). Your server-side event path is the reliable fallback — use it for revenue/signup events where accuracy matters.
  • X-Forwarded-For behind a proxy. If you're behind a load balancer, $request->getClientIp() may be the proxy. Forward the real header explicitly, and make sure your proxy config passes it through (else geo/device data is wrong, not broken).
  • Config cache. In Symfony, changes to config/packages/plausible_analytics.yaml need bin/console cache:clear in dev/prod if you're not in debug — a classic "my domain change did nothing" moment.
  • Extension point: the bundle almost certainly exposes its client as a service. If you need retries, batching, or a kill-switch, decorate that service (Symfony's service decoration) rather than forking the bundle. That keeps you upgrade-safe.
  • Low signal on maintenance. Zero stars/dependents means no community safety net. Pin the version in composer.json, read the composer.json require for the Symfony version constraint (older bundles break on Symfony 7), and have a plan to vendor/replace it — the code is small enough that owning it is cheap.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums