
August 13, 2026
9 min read
Table of Contents
By Kokil Thapa | Last reviewed: August 2026
Setting up multiple storefronts on a single Magento 2 installation reduces operational overhead but introduces complexity that breaks sites when misconfigured. This Magento 2 multi-store configuration guide covers the exact hierarchy, server configuration, and admin settings required to run distinct brands, regions, or languages from one codebase. If you are managing international sales or separate B2B/B2C channels, getting this foundation right prevents costly rework later.
Before touching server configs, understand that Magento’s multi-store architecture is fundamentally different from WordPress multisite or Laravel multi-tenancy patterns I’ve implemented for custom Laravel applications. Magento uses a three-tier hierarchy where configuration cascades downward, and mistakes at the Website level cannot be fixed at the Store View level. For businesses evaluating whether Magento is the right platform versus alternatives, my comparison of Shopify vs WooCommerce for Nepali businesses covers trade-offs relevant to multi-region commerce.
How does the Magento 2 multi-store hierarchy work?
Magento 2 organizes multi-store setups into three distinct scopes: Website, Store, and Store View. Understanding this hierarchy prevents the most common configuration errors I see in production audits.
- Website: The top-level container. Each Website has its own customer accounts, order history, payment methods, shipping methods, and base currency. Customers cannot share carts or accounts across Websites without custom integration.
- Store: Represents a catalog structure within a Website. Each Store has its own root category. Products assigned to one Store’s root category won’t appear in another Store unless explicitly assigned.
- Store View: The presentation layer. Store Views handle language, locale, currency display, and theme selection. Configuration values set here override parent scopes.
A critical distinction: if you need separate payment gateways (eSewa/Khalti for Nepal, Stripe for US), you must create separate Websites. Store Views alone cannot have different payment configurations. On legal-tech portals I’ve built like Court Marriage In Nepal, we used separate Websites for distinct service verticals because each required different payment processing and customer data isolation.
How do you configure Magento 2 multi-store in the admin panel?
Admin configuration must precede server setup. Creating stores via CLI is possible but error-prone; the admin panel validates relationships and creates necessary database entries atomically.
Create the Website
- Navigate to Stores > Settings > All Stores.
- Click Create Website.
- Set Name (internal label), Code (lowercase alphanumeric, e.g.,
np_website), and Sort Order. - Save. Note the auto-generated Website ID for Nginx configuration.
Create the Store
- Click Create Store.
- Select the parent Website from step above.
- Set Name and Root Category. Create the root category first under Catalog > Categories if it doesn’t exist.
- Save.
Create the Store View
- Click Create Store View.
- Select parent Store.
- Set Name, Code (e.g.,
np_en), and Status = Enabled. - Save.
Configure Base URLs per Website
This step causes more production incidents than any other. Go to Stores > Configuration > General > Web:
- In the top-left Scope dropdown, select your new Website (not Default).
- Uncheck Use Website next to Base URL fields.
- Set Base URL and Base Link URL to the domain (e.g.,
https://shop.np.example.com/). Include trailing slash. - Repeat for Secure Base URL if using HTTPS (you should be).
- Save Config.
Common mistake: Leaving "Use Website" checked inherits the default domain, causing infinite redirects or wrong-store content. Always verify by switching scope and confirming the field shows your custom value, not "[website]".
How do you configure Nginx for Magento 2 multi-store domains?
Server-level routing tells Magento which Website/Store View to bootstrap. For subdomain or multi-domain setups, use separate server blocks with MAGE_RUN_CODE and MAGE_RUN_TYPE FastCGI parameters.
<?php
// app/etc/env.php — verify 'directories' and cache config before multi-store
// No changes needed here for basic multi-store; this is for reference only
return [
'backend' => ['frontName' => 'admin_8kLm2'],
'db' => ['connection' => ['default' => ['host' => 'localhost', ...]]],
// Ensure Redis/cache is configured BEFORE adding stores
]; Nginx virtual host for the Nepal store (subdomain example):
server {
listen 443 ssl http2;
server_name shop.np.example.com;
root /var/www/magento2/pub;
# SSL certificates (Let's Encrypt / Certbot)
ssl_certificate /etc/letsencrypt/live/shop.np.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/shop.np.example.com/privkey.pem;
# CRITICAL: Set run code and type BEFORE including Magento conf
set $MAGE_RUN_CODE np_website;
set $MAGE_RUN_TYPE website;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ {
fastcgi_pass unix:/run/php/php8.4-fpm-magento.sock;
fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE;
fastcgi_param MAGE_RUN_TYPE $MAGE_RUN_TYPE;
include fastcgi_params;
# Other standard Magento PHP params...
}
# Static files, media, etc. — standard Magento Nginx rules
location /static/ { /* ... */ }
location /media/ { /* ... */ }
} For store-code-in-URL approach (single domain, path-based stores like /np/, /us/), use a map directive instead of separate server blocks:
map $request_uri $MAGE_RUN_CODE {
default us_website;
~^/np/ np_website;
~^/us/ us_website;
}
map $request_uri $MAGE_RUN_TYPE {
default website;
}
server {
server_name example.com;
# ... same PHP block as above, referencing $MAGE_RUN_CODE/$MAGE_RUN_TYPE
} After updating Nginx, always test configuration before reloading:
sudo nginx -t && sudo systemctl reload php8.4-fpm && sudo systemctl reload nginx If you’re deploying via Deployer 7 (as I do for sister sites like notarykathmandu.com and translationnepal.com), add the Nginx template to your deploy recipe and include the reload task post-symlink. Never edit production Nginx configs manually.
What are the common Magento 2 multi-store pitfalls and fixes?
These issues surface repeatedly in production debugging. Address them proactively.
| Pitfall | Symptom | Fix |
|---|---|---|
| Missing trailing slash in Base URL | Infinite redirect loop, broken admin | Always end Base URL with /; verify in core_config_data |
| Cache not cleared after scope change | Old store content served, config ignored | Run bin/magento cache:flush + setup:static-content:deploy per store |
| Shared customer accounts across Websites | Login fails, cart merges incorrectly | Customers are Website-scoped by design; use API sync if cross-Website needed |
| Static content deployed for wrong locale | Broken CSS/JS, missing translations | Deploy all locales: -f np_NP en_US; check pub/static/frontend/ |
| Indexer not reindexed after catalog change | Products missing, wrong prices shown | Run bin/magento indexer:reindex after assigning products to new root categories |
Database verification: When admin UI seems correct but frontend misbehaves, query directly:
SELECT scope, scope_id, path, value
FROM core_config_data
WHERE path LIKE 'web/unsecure/base_url%' OR path LIKE 'web/secure/base_url%'
ORDER BY scope, scope_id; This reveals mismatched URLs faster than clicking through admin scopes. On a recent eCommerce project for a Nepali grocery store, this query exposed three stores pointing to the same Base URL despite correct admin settings — caused by a failed config import during staging-to-production migration.
How do you maintain and debug Magento 2 multi-store in production?
Ongoing maintenance requires discipline. These practices prevent drift between environments.
- Version-control store configuration: Export
core_config_datafor multi-store scopes viabin/magento app:config:dump. Commit the resultingapp/etc/config.phpto Git. This makes store setup reproducible across staging/production. - Automate static content deployment: In CI/CD pipelines, deploy all active locales explicitly. For a Nepal+US setup:
bin/magento setup:static-content:deploy -f en_US ne_NP --theme=Vendor/theme. Missing locales cause silent frontend failures. - Monitor indexers: Add
bin/magento indexer:statusto health checks. Invalid indexers after product imports serve stale catalog data per store. - Test cross-store isolation: Regularly verify that logging into Website A doesn’t expose Website B’s cart or wishlist. This catches accidental session-sharing regressions after upgrades.
- Document scope assignments: Maintain a spreadsheet mapping SKUs to root categories and Websites. On projects with 5+ stores, this prevents "why isn’t this product showing?" tickets.
When debugging, use CLI to bypass browser caching and CDN layers:
# Verify current store resolution
bin/magento store:list
# Check config value at specific scope
bin/magento config:show web/unsecure/base_url --scope=website --scope-code=np_website
# Reindex single indexer for speed
bin/magento indexer:reindex catalog_product_category For teams managing multiple eCommerce platforms, understanding these Magento-specific patterns avoids applying WordPress or Laravel mental models incorrectly. My guide on website development costs in Nepal breaks down how multi-store complexity affects budgeting across platforms.
Implementing Magento 2 Multi-Store Configuration Correctly
This Magento 2 multi-store configuration guide covers the hierarchy, admin setup, Nginx routing, and production maintenance patterns that prevent real-world failures. Start with correct scope decisions (Website vs Store vs Store View), validate Base URLs via database queries, automate deployments with explicit locale handling, and monitor indexers continuously. Multi-store Magento rewards precision over speed — invest time in foundational configuration to avoid weeks of debugging later. If you need hands-on implementation support for Magento or alternative eCommerce platforms, reach out to discuss your project requirements.

