digifactory/laravel-svg-fixer-middleware
digifactory/laravel-svg-fixer-middleware is a lightweight Laravel middleware that corrects SVG HTTP responses, helping ensure SVG assets are served with the proper headers and render reliably across browsers. A simple drop-in fix for common SVG display issues in Laravel apps.
What the package is. digifactory/laravel-svg-fixer-middleware is a Laravel HTTP middleware that post-processes outgoing responses to normalise SVG markup (the typical fixes: missing xmlns, stray XML prologs/doctype in inline SVG, hard-coded width/height/fill, whitespace/encoding artefacts from design-tool exports). It is glue, not a platform: a single middleware class plus publishable config, wired into the HTTP kernel.
Architecture fit. Good conceptual fit for a Laravel monolith or a Blade-rendered front end where SVGs arrive from Figma/Illustrator exports and get inlined into templates. It occupies the response leg of the kernel, which is the correct seam — no service provider gymnastics, no view-layer coupling, no changes to how designers or front-end devs work. It is a poor fit for API-only services, for apps that pipe SVG through a CDN at the edge (middleware never runs), or for anyone already sanitising SVG at build time in the asset pipeline.
Integration feasibility. Low effort: composer require, register middleware in bootstrap/app.php (Laravel 11+) or Kernel.php, optionally publish config, done. Realistically half a day for one engineer including a regression check on rendered pages. The dominant cost is not installation but verification, because the package mutates response bodies — the blast radius is every HTML and image response it touches.
Technical risk.
$response->getContent() must be scoped by content type and path, or it will eventually touch something it shouldn't (JSON containing SVG strings, downloads, streamed responses).Content-Length / ETag causes truncation or cache-poisoning symptoms that surface as intermittent, hard-to-reproduce bugs in browsers and CDNs.StreamedResponse, BinaryFileResponse, and large responses are the classic failure mode; buffering a big body is a memory and latency tax, and mishandling a stream will silently break downloads.onload, <script>, xlink:href to javascript:). We need to know whether it sanitises or merely corrects — the name says "fixer", not "sanitiser", and assuming the former would be a mistaken control.Release under review (v5.0.1). The only change is a CI-only patch pinning PHPUnit to 12.5.22+. No runtime, API, or config change; no breaking change; no deprecation. Read it as a positive maintenance signal (someone is tending the build) rather than a reason to move. The consequential release is v5.0.0, which is the major-version gate we have not yet assessed — a major bump on this kind of package almost always encodes a Laravel/PHP support-matrix change (dropped older Laravel lines, PHP 8.2+ floor) and possibly config-key or middleware-registration changes. That is the version that determines our integration cost, and it needs a changelog read before we commit.
Key questions.
StreamedResponse, BinaryFileResponse, and non-text/html content types? Any size cap on buffered bodies?Content-Length and ETag, or invalidate them?Cache-Control, spatie/laravel-responsecache, CDN edge caching)? Fix on the fly versus fix at build time — which do we actually want?Recommendation: viable, low-cost, low-ceiling dependency — adopt as a convenience, never as a security control, and only if we can scope it narrowly. The honest counter-position: the functionality is roughly a day of in-house middleware, so if any of questions 1–5 come back unsatisfying, build it ourselves and keep the dependency count flat.
Stack fit. Assumes a Laravel application (10/11/12 class) on PHP 8.2+, server-rendered Blade views, SVGs inlined or served from the app rather than an external CDN. Verify the package's declared illuminate/* constraint against our actual framework version before anything else — that single line decides whether this is a 2025 or a 2026 conversation.
Compatibility.
Migration path. Greenfield enablement, not a migration — there is no data or schema surface.
text/html and image/svg+xml, exclude admin/download routes) rather than accepting a global registration.Sequencing. This is a low-priority, non-blocking piece of work and should be sequenced as such: after any in-flight framework upgrade (so we only validate against one Laravel major), before a design-system refresh (where it pays for itself by ending manual SVG cleanup), and never concurrent with a CDN or response-caching change — those two interact with body rewriting and you will not be able to attribute a regression.
Fallback plan. Feature-flag the middleware registration; because it is a single kernel entry, disabling it is a one-line revert with no state to unwind. Keep a short in-house replacement sketch in the backlog so we are not hostage to the vendor for a cosmetic concern.
Maintenance. Effectively zero steady-state cost: no schema, no background jobs, no persistent state, no external service. Update cadence can be lazy — track it in the quarterly dependency sweep, not the weekly one. v5.0.1 is a dev-dependency pin, which tells us the maintainer is at least keeping CI green; that is the main thing we want to see from a small package. Budget a few hours per framework major to re-validate.
Support. Single-maintainer, small-userbase open source. Do not build an escalation path that assumes vendor responsiveness; build one that assumes we can fork or replace it in a day. That is cheap here precisely because the surface is small.
Scaling. Cost is per-response and proportional to body size on matched routes — one buffer + one string transform on HTML responses. On SVG-heavy pages with large inline sprite sheets this is measurable but small; on high-RPS endpoints it is pure overhead for no benefit, which is the argument for route scoping over global registration. It scales horizontally with no shared state. Watch memory on responses with large inlined SVG (some sprite sheets are hundreds of KB), and confirm the middleware does not force buffering of responses it would otherwise leave streamed.
Failure modes and detection.
Content-Length/ETag — truncated or mis-cached pages, often only visible behind a CDN. Verify headers on a canary before full rollout.Ramp-up. A Laravel developer is productive in under an hour; there is nothing to learn beyond "it rewrites responses, here is where it is registered." The people who actually need briefing are front-end and design-ops — the win is that they stop hand-editing SVG exports, and the behavioural expectation to set is that markup will be silently normalised, so "why does my SVG look slightly different in prod" has an answer before it is asked. Total onboarding investment across the team: negligible.
TPM summary. Low-risk, low-cost, low-ceiling utility. Value is developer-time recovered from manual SVG cleanup plus a class of asset-quality bugs that stop reaching users. Cost is one more small dependency and a modest verification exercise. Proceed if the v5.0.0 compatibility check and the sanitisation question both come back clean; otherwise build the ~1-day equivalent in-house and skip the dependency entirely.
How can I help you explore Laravel packages today?