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

Channel Bundle Laravel Package

sylius/channel-bundle

Sylius Channel Bundle adds channel management to Sylius e-commerce applications, letting you define multiple sales channels with their own currencies, locales, tax and shipping settings, and manage them through the admin panel for multi-channel storefronts.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the framing: this is not a Laravel package. sylius/channel-bundle is a read-only subtree split of Sylius/Sylius, and it's a Symfony bundle (Form/DI/Doctrine/Twig + sylius/resource-bundle). There's no service provider, no Eloquent, no Blade. So "day-to-day leverage" splits into two real scenarios:

  1. You're in a Sylius app — the bundle is already installed transitively via sylius/sylius. Never composer require it directly; pin the platform, not the split.
  2. You're in Laravel — use the repo as a reference implementation of channel semantics. Read it, don't install it.

Confirm what you have (Sylius path):

composer show sylius/channel-bundle   # version must match sylius/sylius
bin/console debug:container | grep sylius.channel
bin/console debug:config sylius_channel

Where to look first:

  • src/DependencyInjection/Configuration.php — the real knobs (which channel features are toggleable).
  • src/Form/Type/ChannelType.php — every field a channel carries (locales, currencies, tax zone, shipping/payment method associations, hostname).
  • src/Resources/config/** — services, resource registration, grid definitions. This is the documentation.
  • The Sylius docs on "Channels" in the main monorepo, since this repo has no standalone docs.

First use case: create a second channel (e.g. WEB-US alongside the seeded WEB-EU), give it its own hostname, default locale, default currency, and tax zone, then load the storefront under that hostname and confirm the correct locale/currency resolve. That single end-to-end pass touches every part of the bundle.

Laravel equivalent of "getting started": clone the repo, read ChannelType and Configuration, and sketch the same entities — Channel{code,name,hostname,default_locale,default_currency,enabled,tax_zone_id} plus channel_product and channel_price_list pivots. That's a day of reading and a day of scaffolding.

Implementation Patterns

Sylius: channel provisioning via fixtures, not clicks. Manual admin channel creation drifts across environments. Define channels in YAML fixtures and load them through the resource stack; that keeps staging/prod aligned and makes code review of channel config possible.

Sylius: inject channel context, don't re-resolve it. The channel is resolved once per request (hostname first, then an explicit override for admin/API traffic) and stored on the request/context. In controllers and services, consume the already-resolved channel — don't re-query by hostname in every service. If you write custom services, take the channel (or a channel context service) as a constructor dependency so they're testable.

Sylius: extend ChannelType with a form extension, not a fork. Custom channel fields (ERP account code, brand palette, feature flags per storefront) go in a ChannelTypeExtension plus a Channel entity extension mapped via sylius_channel resource config. This is the intended customization seam and survives upgrades; editing vendor code does not.

Sylius: grid customization for channel admin. The channel admin grid is a Sylius resource grid — add columns/filters in YAML under sylius_grid. Use it to surface per-channel locale/currency counts and enabled flags, which is where ops actually notice misconfiguration.

Sylius: channel-scoped queries at the repository layer. Any catalog/pricing query must be constrained by channel. Put that constraint in a custom repository method or query-builder decorator so it can't be forgotten at a call site. If a developer can write a product listing query without mentioning the channel and still get results, the pattern is broken.

Sylius: validate channel uniqueness early. Hostname and code uniqueness are the two constraints that break routing and pricing when violated. Enforce via validator constraints on the form type so the failure surfaces in the admin UI, not as a 500 at checkout.

Laravel: port the semantics, not the code. Idiomatic equivalents:

  • ChannelContext singleton bound in the container, populated by a ResolveChannel middleware (hostname → cache → DB fallback).
  • Eloquent global scopes or a ChannelScoped query builder trait for catalog/pricing models.
  • A channels table plus channel_product, channel_price_list pivots.
  • Cache the hostname→channel map (Cache::remember('channel:host:'.$host, ...)) and invalidate explicitly on channel save.
  • An explicit override header (X-Channel-Code) for admin/API/queue contexts, mirroring Sylius' ability to operate outside request-host resolution.

Laravel: interoperate at the API boundary if a Sylius instance exists. If a Sylius store already owns channels and pricing, don't dual-host Symfony inside Laravel — expose channels via API/queue messages and have Laravel read a materialized channel view. The Composer boundary is the right boundary.

Testing pattern (either path): write a request-level test per channel — assert resolved channel, default locale, currency, and negative assertions that a product/price from channel A is absent in channel B. The leakage bugs are the expensive ones, and they only show up in cross-channel assertions.

Gotchas and Tips

Never add this as a direct Composer requirement. Version skew between the split and sylius/sylius is the classic breakage. Let it arrive transitively.

Don't try to bridge it into Laravel. Embedding the Symfony kernel, dual ORM, or shared entities is technically possible and economically indefensible for a single bundle. The TPO assessment is right: the bundle is integration glue, not a feature set. Take the concepts, skip the dependency.

The 3 stars / 0 dependents is not a quality signal — it's a monorepo artifact. But it does mean: no issue tracker here, no standalone docs, no community patterns. Every bug routes to the Sylius monorepo. Budget for one named owner with Sylius experience, or accept slow incident resolution.

Silent cross-channel failures are the real risk. Watch for:

  • Price leakage (customer sees another channel's pricing).
  • Wrong currency/locale from a misconfigured or duplicate hostname.
  • Carts/orders attached to the wrong channel at checkout (usually a resolution-order bug or a stale cache).
  • Catalog visibility bleed (product published to A appears in B).
  • Tax zone / shipping method misassignment after a channel edit.

Build a smoke test that hits each channel's storefront and asserts the resolved currency, locale, and a known product's presence/absence.

Cache invalidation is manual and easy to forget. The hostname→channel map (in Sylius' router context and in any Laravel port) must be invalidated explicitly when a channel's hostname, enabled flag, or defaults change. Cache staleness after a config change is a recurring operational failure mode.

Channel count is a product decision with a real cost. Each channel multiplies price rows, catalog rows (via pivots), tax/shipping configuration, and content. It's also a query-plan concern — channel-scoped queries must stay index-friendly (index channel_id on every pivot and price table).

Locale/currency fallback chains need explicit design. A channel's locales list plus a fallback locale is easy to configure in a way that "works" in one storefront and produces untranslated content in another. Test with a channel that has a locale missing a translation.

Sylius 1.x → 2.x is the friction point (Symfony 6/7, PHP 8.2+, revised bundle/admin architecture). Pin the platform version and treat this bundle as an implementation detail; plan the upgrade as a platform upgrade, not a bundle upgrade.

Extension points to prefer: form type extensions, resource config overrides (entity, repository, grid), DI service decoration, and fixtures. Avoid: copying vendor templates, editing src/Resources/config in place, or subclassing the channel entity outside the resource extension mechanism — all three turn every platform upgrade into a manual merge.

Debugging tips: bin/console debug:config sylius_channel, debug:container --tag=sylius.channel_context (or grep for the context service), and bin/console sylius:debug style commands from the platform. When channels behave oddly in the admin, check the grid config and resource registration before suspecting the entity — most "the field disappeared" bugs are resource-config overrides.

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.
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment