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

Multi Site Bundle Laravel Package

freshheads/multi-site-bundle

A Symfony bundle for running multiple websites from one codebase, with per-site configuration, routing, and content isolation. Simplifies multi-site management without duplicating application logic.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — poor as a direct dependency, moderate as a reference implementation. The package remains a Symfony bundle (FHMultiSiteBundle), not a Laravel package. Release 1.3.0 adds Symfony 7 support, which confirms rather than softens this verdict: the bundle is explicitly tracking Symfony major versions, so its integration contract is a bundle class in bundles.php, a DI extension with a Configuration tree, compiler passes, and Symfony route loaders/listeners. None of that exists in Laravel. Laravel has its own container, service-provider lifecycle, and router — although Illuminate\Routing\Route extends Symfony\Component\Routing\Route, so a narrow slice of the routing surface is conceptually shared. The transferable value is still the design: a site registry, a resolver mapping an incoming request (host and/or path prefix) to a site, and route-registration strategies keyed by site.

Integration feasibility — low for composer require, moderate-to-high for a port. Unchanged. A 200–400 line spike remains sufficient to decide whether the resolver logic is worth lifting. The realistic outcomes are still (a) reimplement the resolver and site registry natively using Route::domain() groups plus a ResolveSite middleware, or (b) pull a non-Symfony core subset if one cleanly exists. The 2024–2025 activity does not change the estimate; if anything the Symfony 7 retarget makes the code less likely to be framework-agnostic, since it now leans on current Symfony DI and attribute conventions.

Technical risk — high, but the risk profile has shifted from "abandoned" to "maintained-but-idle."

  • Abandonment/bus factor — partially improved, not resolved. 1.3.0 supersedes the 2024-06-05 release and shows real activity: a Symfony 7 compatibility PR (#21), PHPStan adoption (#18) with follow-up deprecation cleanup (#20), a changelog-enforcer workflow (#19), and a php-cs-fixer shim dev dependency (#17). There is also a new contributor (@bart-van-amelsvoort). Read this correctly, though: it is a maintenance/tooling release with zero feature or API changes. Stars and dependents are still effectively nil, there is still no third-party security review, no SLA, and the contributor is doing housekeeping, not building a community. Treat it as "vendor responds to framework majors on their own schedule," not as "this is a safe upstream to depend on."
  • Version drift — the original blocker is now confirmed, and the answer doesn't help us. 1.3.0 targets Symfony 7, meaning the bundle almost certainly requires symfony/framework-bundle at 7.x and PHP 8.2+. That is the same Symfony generation Laravel 11 draws components from — so the earlier worry ("component version mismatch inside Laravel") is now moot. The terminal problem is unchanged: a bundle requiring framework-bundle will never boot in Laravel regardless of version alignment. One thing to check: adding Symfony 7 in a 1.x minor is a constraint-level breaking change — diff composer.json across 1.2.1 → 1.3.0 to see whether Symfony 5.4/6.x support was dropped. For us this matters only as evidence of how tightly the site-registry configuration is welded to Symfony's config component.
  • Code quality signal — mildly positive. PHPStan at a configured level plus deprecation cleanup means the reference implementation is now more legible and less likely to encode patterns that were already deprecated on Symfony's side. That raises the reference value slightly; it does not raise adoption feasibility.
  • Hidden coupling — unchanged. The real risk remains undiscovered behavior inside compiler passes, route loaders, and cache warmers — logic with no Laravel analogue that must be re-derived rather than copied.
  • Opportunity score — unchanged at 28.05. Even on native Symfony turf this is not a high-leverage bet. The opportunity cost of a bespoke port should be weighed against Laravel's built-in domain routing and existing multi-tenant packages.

Key questions for the spike owner (revised):

  1. What are the PHP and Symfony constraints, and does it hard-require framework-bundle? Partially answered. 1.3.0 implies framework-bundle 7.x and PHP 8.2+. Confirm by reading composer.json and diffing against 1.2.1: specifically, were Symfony 5.4/6.x constraints dropped, and is the PHP floor now 8.2?
  2. Is site resolution host-based, path-prefix-based, or pluggable? Is there a strategy interface we can port verbatim?
  3. How does it hook routing — a custom RouteLoaderInterface, PHP attributes, a compiler pass, or a request listener? Can that be expressed as Laravel route groups? (The Symfony 7 retarget makes attribute-based registration more likely — check whether registration moved from YAML/XML to attributes, and whether that logic survives translation.)
  4. Is site configuration schema-first (typed config tree) or free-form YAML? Can it map to config/sites.php?
  5. Does it handle cross-site URL generation, and how does it avoid leaking another site's domain into route() output?
  6. Does it partition cache, session, and cookie scope per site, or leave that to the host app?
  7. Is Fresh Heads willing to accept patches? Slightly better evidenced — a new contributor landed four PRs in this cycle — but responsiveness on framework majors ≠ responsiveness on security. Do not plan around their release cadence.

Integration Approach

Stack fit. Treat the bundle as a specification, not a dependency. 1.3.0 does not change the mapping:

Bundle concept Laravel equivalent
Site configuration tree config/sites.php with a typed array schema, validated at boot
Site resolver / repository Singleton SiteResolver bound in a service provider
Routing strategy per site Route::domain() groups, or per-site RouteServiceProvider
Request-scoped site context ResolveSite middleware + a CurrentSite scoped binding
Template/locale switching Middleware-set locale and view namespace

Migration path. Still no shim or adapter layer — the bootstrapping models are incompatible, and a shim would carry all the maintenance burden with none of the upstream benefit. Sequence, lightly revised:

  1. Read-only audit (1 day, was 1–2): clone at the 1.3.0 tag, read the resolver and routing strategy classes, record the config schema and resolution precedence (exact host vs. wildcard vs. path prefix, tie-breaking). The PHPStan config and deprecation cleanup shorten this step.
  2. Config schema decision (1 day): define config/sites.php — host list, path prefix, locale, asset/theme root, per-site feature flags. Decide static enumeration vs. database discovery.
  3. Resolver + middleware spike (2–3 days): implement ResolveSite, bind a request-scoped CurrentSite, add a 404/fallback policy for unknown hosts. Test explicitly under Octane and queued jobs.
  4. Route registration (2–4 days): convert the bundle's routing strategy into domain-constrained route groups; ensure route() and signed URLs resolve against the current site.
  5. Cross-cutting concerns (3–5 days): per-site cache prefixes, session cookie domains, file storage roots, mail from-addresses, log context.
  6. Test harness (2–3 days): feature tests asserting host→site resolution, cross-site URL isolation, unknown-host fallback.

Budget remains roughly 2–3 engineering weeks for a hardened port with tests; the spike alone is under a week.

Compatibility — materially clearer after 1.3.0. The bundle now targets Symfony 7 and therefore PHP 8.2+, and modernized DI conventions (autowiring, likely attributes) are closer in spirit to Laravel's container than the older service-alias style would have been. That is a modest win for readability, not for installability. Two concrete checks: (a) diff composer.json between 1.2.1 and 1.3.0 to confirm the dropped Symfony/PHP floors and to see whether symfony/framework-bundle is a hard require versus a suggest; (b) confirm the Laravel version in use ships a Symfony component generation we can reason about. Neither check changes the outcome — framework-bundle has no Laravel analogue to boot against.

Sequencing note. Unchanged and still the gating question. This work is only justified if the product genuinely requires per-site configuration divergence (locales, themes, feature flags), not merely multiple domains pointing at one app. If the requirement is "serve several hostnames from one codebase," Route::domain() plus a small host→tenant map covers it in a day, and neither this bundle nor a port of it adds anything.

Operational Impact

Maintenance. We own it after porting, and 1.3.0 does not change the economics: no security advisories, no compatibility guarantees, no roadmap. A Symfony 7 PR in a 1.x minor is evidence they can move, not evidence they will move on our timeline — and given nil dependents, there is no ecosystem pressure forcing them to. Add the ported resolver and middleware to the internal ownership register with a named maintainer. The steady-state cost is low (small, stable logic), but the unowned dependency risk of installing a low-adoption Symfony bundle into a Laravel app remains severe enough to reject outright.

Support. MIT, no vendor SLA, documentation limited to the repository README. Any production incident traces to our own ported code, which is the favorable outcome — we can read and fix it. 1.3.0 adds a changelog-enforcer, which marginally improves release-note hygiene; it does not create a support channel. Keep no Composer entry, so nothing to cite in dependency inventories or vulnerability-scan exemptions.

Scaling. Resolution is O(1) against an in-memory config map and effectively free. The real scaling concerns are the ones the bundle likely leaves to the host application, and 1.3.0 touches none of them:

  • Cache partitioning: every cache key, view cache entry, and config-cache artifact must be namespaced per site, or sites leak rendered content to each other.
  • Session and cookie scope: cookie domains must be set per site; a shared session cookie across independent brand domains is a correctness and privacy problem.
  • Worker state: queue workers, Octane, and any long-lived process must reset CurrentSite between jobs/requests — the single most likely production bug class in a Laravel port.
  • Config cache: a large site registry inflates config:cache; fine for tens of sites, reassess for hundreds.

Failure modes to design against explicitly:

  1. Unknown host — hard 404, redirect to canonical site, or default to primary; the bundle's own choice may not match our policy.
  2. Route collisions — two sites sharing a path with different controllers; domain constraints must be mandatory, not advisory.
  3. Missing middleware — a route registered outside the site-aware group runs with no site context; enforce via route-group convention or global middleware.
  4. Cross-site URL leakage — route()/url() emitting another site's domain, typically surfacing in emails and sitemaps. Test it.
  5. Context bleed under Octane — resolved site persisting into the next request.
  6. Config drift — sites added to the registry but not to DNS/certs, or vice versa; validate at deploy time.

Ramp-up. Marginally improved. A Symfony-fluent engineer reads the 1.3.0 code in half a day, helped by PHPStan-passing, deprecation-cleaned, Symfony 7-era idioms. A Laravel-only team still spends 1–2 days mapping bundle conventions onto service-provider idioms before being productive. Keep the concept briefing short and the policy decisions long: the effort is not understanding the code but settling unknown-host behavior, per-site cache/session scoping, and where site context must be threaded through. Those are product-facing decisions and should be settled before the port begins, not discovered during it.

Recommendation — unchanged. Do not adopt. Use 1.3.0 as a design reference for a small, owned Laravel implementation, contingent on validating that per-site configuration divergence is a real requirement rather than a multi-domain routing need Laravel already satisfies. The release reduces the "dead upstream" concern but does not change a single line of the integration calculus: it is a Symfony bundle, we are a Laravel shop, and the port was always the plan.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console