@alireza_hadizadeh Branches is not really the solution. You should be deploying from a single branch (i.e. main) rather than having different branches for different clients, as that’s just not maintainable.
I have a similar project: a multi-tenant CMS that hosts websites for multiple clients. A bit like a small Wix or Squarespace. There’s a single codebase, but then each customer has their own “website” with its own pages, design, etc.
I tackled this by having “base” templates and then defining a Blade view namespace in middleware which searches two paths for Blade templates: a website-specific template, before falling back to the “global” templates:
class DefineViewNamespace
{
public function handle(Request $request, Closure $next)
{
// Get website from route-model binding
$website = $request->route('website');
View::addNamespace('website', [
resource_path(sprintf('vendor/%s', $website->slug)), // Website-specific path
resource_path('views/website'),
]);
return $next($request);
}
}
So this will look for a website-specific template in resources/views/vendor/{website slug} and if a template isn’t found, fall back to looking in the resources/views/website directory. It means I can then define overrides on a per website basis.
I also make heavy use of feature flags as @pluma suggests. For example, some websites have a shop and others don’t. So I can use feature flags (powered by Pennant) to conditionally show shop-related things such as navigation items:
<li>
<a href="{{ route('website.home', compact('website')) }}">
{{ __('Home') }}
</a>
</li>
@feature('shop')
<li>
<a href="{{ route('website.shop.home', compact('website')) }}">
{{ __('Shop') }}
</a>
</li>
@endfeature