loophp/go-unfloc-yourself-bundle
The Go Unfloc Yourself Bundle is a Symfony bundle that opts your site out of Google's FLoC interest-cohort tracking. It automatically sets the Permissions-Policy interest-cohort header, keeping visitor data out of cohort-based ad targeting with almost no configuration.
This is a Symfony bundle, not a Laravel package — the -bundle suffix and the loophp namespace are the tells, and the 1.0.0 release notes ("Initial set of files.") give no README or config documentation to contradict that. Its purpose, from the name, is to opt HTTP responses out of Google's FLoC interest-cohort tracking by emitting the Permissions-Policy: interest-cohort=() header (historically Feature-Policy: interest-cohort 'none').
What that means for you in practice:
composer require loophp/go-unfloc-yourself-bundle will install it, but nothing will run. There is no Illuminate\Support\ServiceProvider, no package auto-discovery, no config/ publish tag. Laravel has no registerBundles() kernel, so the bundle's DI extension and response listener never fire.src/EventListener/ or src/EventSubscriber/) and the DependencyInjection/ extension. That's where the header name/value is hard-coded and where you'll see which Symfony event it hooks (kernel.response, almost certainly). This is a ~50-line package; reading it takes two minutes and tells you 100% of the behavior.UnflocYourself middleware and register it globally. That is a 20-line copy of intent and zero Symfony coupling.If you want the concept without the port, set the header at your web server / CDN instead — it's a static value.
Global middleware (recommended). The bundle's Symfony listener maps 1:1 onto Laravel middleware. In Laravel 11+, register it in bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) {
$middleware->append(\App\Http\Middleware\UnflocYourself::class);
})
For Laravel 10 and below, add it to $middleware (the global stack) in app/Http/Kernel.php.
Merge, don't overwrite. The one genuinely important implementation detail is that Permissions-Policy is a comma-separated list of directives. If your app or a CDN already sets camera=(), microphone=(), geolocation=(), a naive $response->headers->set(...) silently drops them. Read the existing header, append the directive, write back.
Event listener alternative. If you prefer not to touch the middleware stack, hook Illuminate\Foundation\Http\Events\RequestHandled in AppServiceProvider/EventServiceProvider — it is the direct analogue of Symfony's kernel.response and keeps the port conceptually faithful to the bundle.
Config-driven. Mirror whatever the bundle's DI extension exposes as a toggle into config/unfloc.php ('enabled' => env('UNFLOC_ENABLED', true)), checked inside the middleware. This lets you switch it off per-environment instead of editing code.
Testing pattern. Feature-test the header explicitly: $this->get('/')->assertHeader('Permissions-Policy', 'interest-cohort=()'), plus a test asserting an existing Permissions-Policy value is preserved and extended.
composer require as working protection — verify with curl -I https://yourapp.test/.interest-cohort is a no-op in current Chrome. Treat this as privacy hardening / compliance hygiene (and a cheap win for audit checklists), not active anti-tracking protection. Don't let it create false assurance in a privacy review.Feature-Policy: interest-cohort 'none'; the modern form is Permissions-Policy: interest-cohort=(). Check which one the bundle actually emits before copying it into middleware — 1.0.0 is a single-commit initial release and may not have settled on the current syntax.Permissions-Policy is already set by a security package, session, or an upstream proxy, ordering of global middleware determines which wins. Append rather than overwrite, and position your middleware after whatever sets the baseline.composer.json and read the source before depending on it — or just inline the middleware and drop the dependency entirely.enabled flag at most. If you need conditional behavior (e.g., only on HTML responses, only outside admin routes), you are writing that yourself in the middleware — don't expect the bundle's config tree to cover it.How can I help you explore Laravel packages today?