hengebytes/response-filter-bundle
Response Filter Bundle for Laravel/PHP adds a configurable layer for trimming, transforming, or hiding response fields before data reaches the client. Define filters, apply them globally or per route, and keep API payloads lean without editing controllers. Lightweight, quick to install, and simple t...
The headline of v1.1.0 is that you no longer need Twig (or any templating layer) to define response filter rules — php artisan hb_response_filter:manage is now the management surface. Treat that command as your entry point before touching any config file.
Install and discover the surface area first.
composer require hb/response-filter
php artisan vendor:publish --tag=hb-response-filter-config # verify tag name in the package README
Then immediately run php artisan hb_response_filter:manage with no arguments. The interactive menu it presents is the authoritative list of what the package can do in this release — rule types, scopes, and where rules are persisted (config file vs. database). Read that output before reading the source; it tells you which storage driver you are on.
Create one rule end-to-end before wiring anything else. Run the manage command, add a single literal find/replace rule (e.g. swap a placeholder domain for the real one), and hit a route. Confirm the substitution happens on a real text/html response. This validates three things at once: the middleware is registered, the rule store is readable at runtime, and your rule ordering is sane.
First real use case: environment-specific string rewriting — swapping staging URLs, analytics IDs, or asset hosts in rendered HTML without redeploying templates. This is the lowest-risk, highest-signal use of the package and maps directly to the "no Twig" story: rules live in data, not in view code.
Rules as data, not code. The core workflow shift in this release is that filter rules are managed operationally via hb_response_filter:manage rather than templated. This means rules can be adjusted per environment and, depending on the configured driver, without a deploy. Keep rule definitions out of your Blade templates entirely — the moment a rule leaks into a view, you have reintroduced the coupling the package is designed to remove.
Scope rules narrowly and deliberately. Establish a convention for which routes the filter middleware attaches to. Two common shapes:
Prefer the narrow option by default; widening scope later is cheap, debugging a regex that mangled a JSON payload is not.
Layer rules in a known order. Most response filters apply sequentially, so the first rule's output is the second rule's input. When using the manage command, name rules with an explicit numeric or alphabetical prefix so ordering is visible in the listing and stable across edits. Rules that are order-independent should be written to be idempotent where possible.
Treat the manage command as a config-management step in CI. If rules are persisted to a file or database, capture that state in version control or a seeded migration. A workflow that works well: developers iterate interactively with hb_response_filter:manage, then the resulting rule set is exported and committed so staging and production are reproducible rather than hand-edited.
Integration tip: verify with assertions, not eyeballs. Add a feature test that requests a representative route and asserts the filtered output. Response filtering is exactly the kind of transformation that silently stops applying after a middleware priority change or a cache-layer introduction, and a single assertion catches it.
The command is a management UI, not a migration. Running hb_response_filter:manage in a fresh environment will not necessarily recreate rules that only existed in a developer's local store. Confirm where rules are persisted the first time you use it, and make that location deployable. This is the single most likely source of "works on my machine" incidents with a manage-command-driven configuration model.
Response body access is not universal. Filters that assume a string body will break on streamed responses, file downloads, and binary payloads. Confirm the middleware skips non-textual content types, and if it does not, scope the middleware so it never sees those routes.
Watch Content-Length and caching. Replacing a string with one of a different length invalidates a precomputed Content-Length header and can confuse downstream caches. If you filter compressed or cached responses, verify behaviour against your actual stack (nginx, Varnish, Laravel's response cache) rather than assuming the middleware runs at the right point.
Middleware priority matters. If another middleware short-circuits (e.g. a full-page cache returning early), your filters never run. Place the filter after cache middleware when you want cached responses filtered, or before it when you want the filtered output cached. Decide deliberately and write it down.
Regex rules are the sharpest tool available. Any rule supporting patterns can match far more than intended. Anchor patterns, prefer literal matching where it suffices, and test a rule against a saved real response before promoting it. Because rules are applied at request time, a catastrophic-backtracking pattern is a production outage rather than a slow test.
Debugging approach: when a rule appears not to fire, check in this order — (1) does the response's content type match what the filter accepts, (2) is the middleware actually attached to that route (php artisan route:list -v), (3) is the rule enabled and ordered before a rule that rewrites the same text, (4) is an upstream cache serving a pre-filtered body.
Extension points. With the Twig dependency removed, custom logic now belongs in whatever rule types or filter classes the package exposes rather than in templates. If you need conditional or computed replacements, look for a custom filter/resolver hook and register it in a service provider — this keeps the manage command as the single inventory of rules while allowing logic that a static rule cannot express. Verify the exact interface names against the package source before building on them; this release's removal of Twig suggests the extension surface changed and older examples may no longer apply.
Upgrade note for existing Twig-based setups: if you previously defined rules as Twig templates, this release's direction implies those need to be re-authored as managed rules. Inventory existing templates before upgrading — a silently ignored template rule fails open, meaning unfiltered output reaches users with no error.
How can I help you explore Laravel packages today?