ongr/ssi-bundle
Symfony bundle that adds Server Side Includes (SSI) support, letting you compose pages from independently rendered fragments. Useful for caching dynamic blocks and integrating SSI-enabled web servers with Symfony controllers and templates.
Architecture fit. ongr/ssi-bundle is a Symfony2 bundle, not a Laravel package — a catalog mismatch worth flagging immediately. Its value proposition is narrow: emit Server Side Include directives (e.g. <!--#include virtual="/fragment/cart"-- >) so an upstream web server (nginx ssi on, Apache mod_include, Varnish ESI) can assemble cached page shells with dynamic holes. Architecturally it binds to Symfony's bundle registration (AppKernel), DI container, config tree, and its fragment/hinclude rendering conventions. Laravel has no bundle system, so the package cannot be composer required and used as-is; it would need a bridge (service provider, config publishing, Blade directive, fragment route) or a parallel Symfony micro-kernel whose only job is to host the fragments — infrastructure duplication for a feature that is essentially string templating.
Integration feasibility. Low as a drop-in; moderate as a source of design. The genuine logic is small: a directive builder, a renderer service, and configuration for fragment paths and attributes. Adapting means vendoring the source, stripping Symfony metadata, and re-implementing the public surface in Laravel idioms — roughly a one-to-two-day spike for a competent engineer, versus a one-hour spike to read the code and write the equivalent from scratch. The SSI contract itself is plain HTTP, so a Laravel-served fragment endpoint works with a Symfony front end (or vice versa) without any code sharing.
Technical risk. High. The repository is in the ongr-archive organization — explicitly read-only and abandoned. Last release was 2014-10-10, targeting PHP 5.x and Symfony 2.x; Symfony 2 reached end of life in 2018 and PHP 5.6 in 2018, so there are no security patches, no maintained transitive dependencies, and no CI signal. Two stars and zero dependents means no evidence of production hardening and no community to absorb defects. Modern Symfony components pulled by Laravel (symfony/http-foundation ^6/^7, symfony/http-kernel) will likely conflict with the pinned 2.x constraints, so the package may not even install cleanly in a current application. SSI also introduces a security surface: if any user-controlled value reaches a directive, the app is exposed to SSI injection and path traversal, and the abandoned code offers no mitigations. Software composition analysis will flag the dependency and can block builds.
Key questions.
fastcgi_cache) that makes SSI redundant?Recommendation: treat this as a reference implementation, not a dependency. The concept is worth adopting; the package is not.
Stack fit. Laravel-first, and the integration is a port rather than an install. The minimal viable shape: a config file declaring fragment routes and default attributes, a singleton renderer that builds the directive string, a Blade directive (@ssi('cart') / @ssi('cart', ['user' => $id])), a controller (or invokable route) that renders fragments and returns them with explicit cache headers, and middleware that sets Cache-Control/Vary correctly on both the shell and the fragment responses. If the application is Symfony 2/3 and staying there, the bundle fits its native environment — but that environment is itself a liability.
Migration path. Do not attempt an in-place composer require in the Laravel app. Clone the repository into a scratch directory, read the directive-generation and fragment-resolver logic, and note the exact tag format and attribute encoding it produces, since that is the wire contract the web server depends on. Then write the equivalent in the application's own namespace. If a legacy Symfony application already uses the bundle, preserve the directive format verbatim so the web server config and cache keys remain stable, and migrate the generation side incrementally behind a feature flag. The boundary is HTTP, so the two frameworks can coexist during transition.
Compatibility. Assume PHP 8.1+ will surface deprecations (dynamic properties, each(), implicit nullable parameters) and that Symfony 2.x constraint sets will conflict with anything modern. Verify composer why-not before considering installation. Confirm the web server module is compiled in (nginx -V | grep -i ssi, or mod_include present) in every environment, including local Docker and CI, so behavior does not diverge from production. Check whether the chosen cache tier honors ESI versus SSI syntax — they are not interchangeable, and using the wrong one yields silent blank regions rather than errors.
Sequencing.
Vary handling for personalized fragments.Maintenance. Ownership transfers to us on day one. Upstream is archived and read-only; with zero dependents there is no chance of a shared fix if a defect surfaces. A fork must be tracked as internal code with its own review, tests, and dependency updates — for a package whose useful surface is a few dozen lines, that is a poor maintenance-to-value ratio. Expect SCA tooling to flag the dependency and require an explicit exception if it is ever installed rather than ported.
Support. None. No maintainer, no issue triage, no security advisory channel, no documentation beyond a 2014 README. Internal onboarding happens by reading source, not by referencing docs. Any incident traces to our own fork, so the on-call story must be defined before launch — most likely "disable SSI directives, serve the fragment inline" as the rollback.
Scaling. The architecture can genuinely help: a cached shell with a handful of SSI holes shifts work off PHP and lets the edge serve most requests, improving throughput and time-to-first-byte. That benefit is conditional on cache-hit discipline, correct Cache-Control and Vary headers, and tight fragment rendering. Costs to watch: subrequest fan-out (each hole is a separate HTTP fetch, so a page with fifteen fragments can be slower than one PHP render under low cache-hit rates), connection overhead to the upstream, and personalization that fragments the cache into uselessness. Measure shell hit ratio and per-fragment p95 before claiming a win.
Failure modes. The dangerous ones are silent. Malformed directive syntax renders nothing — users see empty holes, not errors, and no exception fires. A missing or renamed fragment route yields a 404 embedded in an otherwise healthy page. SSI enabled in staging but off in production (or vice versa) produces environment-specific layout bugs that are hard to attribute. Recursive includes (a fragment that includes itself) can loop or truncate the response. Unescaped user input reaching a directive is an injection vector. Abandoned dependencies also fail at the build layer, blocking CI after an unrelated lockfile refresh. Mitigation: treat every hole as a monitored entity — assert non-empty fragment output in integration tests, alert on fragment 4xx/5xx rates, and escape all directive attributes at the renderer boundary.
Ramp-up. Conceptual ramp-up is fast — SSI is a simple, well-documented mechanism and most engineers grasp it in an afternoon. Operational ramp-up is the real cost: the team must understand cache tiers, header semantics, web server configuration, and how to observe a system whose output is assembled after PHP exits. Budget roughly one sprint for the in-house implementation plus tests, and separate platform time for web server and cache configuration across all environments. The knowledge that matters here is infrastructure, not framework internals — staff it accordingly, and do not let the "it's just a template helper" framing hide the caching and observability work that determines whether the approach pays off.
How can I help you explore Laravel packages today?