Magento Multi-Store Setup Overview Magento's multi-store architecture has three levels: Website → Store → Store View. A Website groups stores with a shared customer base and order flow. A Store (under a Website) has its own root category and URL structure. Store Views (under a Store) typically represent languages or locales. Configuration values can be set at Global, Website, or Store View scope — lower scopes override higher ones. Adobe Commerce (B2B) adds Shared Catalogs for per-company product/price visibility control. When to Use This Skill - When running multiple brands or country-specif…

block, not outside it at the server level\"\n },\n {\n \"name\": \"Language storefronts use store routing\",\n \"max_score\": 10,\n \"description\": \"UK and German storefronts are mapped to MAGE_RUN_TYPE 'store', not 'website'\"\n },\n {\n \"name\": \"B2B portal uses website routing\",\n \"max_score\": 10,\n \"description\": \"B2B portal is mapped to MAGE_RUN_TYPE 'website'\"\n },\n {\n \"name\": \"hostnames keyword in map blocks\",\n \"max_score\": 6,\n \"description\": \"map blocks include the 'hostnames' keyword to enable hostname-based matching\"\n },\n {\n \"name\": \"Notes explain store vs website distinction\",\n \"max_score\": 10,\n \"description\": \"Documentation explains that 'store' routing is chosen for language variants that share a customer base, while 'website' routing is chosen for the B2B portal because it requires a separate customer base\"\n },\n {\n \"name\": \"Default empty values in map\",\n \"max_score\": 7,\n \"description\": \"map blocks include a 'default' entry mapping to an empty string for unrecognized hosts\"\n },\n {\n \"name\": \"No MAGE_RUN_CODE in index.php\",\n \"max_score\": 12,\n \"description\": \"The configuration does NOT set MAGE_RUN_CODE or MAGE_RUN_TYPE inside a PHP file (index.php or similar) — routing is handled entirely at the nginx level\"\n },\n {\n \"name\": \"MAGE_RUN_CODE uses store view codes for store-type routes\",\n \"max_score\": 12,\n \"description\": \"For domains mapped to MAGE_RUN_TYPE 'store', the corresponding MAGE_RUN_CODE value is a store view code (not a website code)\"\n }\n ]\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":2755,"content_sha256":"180257aaf7ec95ebcb8867a08f19578be9d907fe373df5b96cf46f35c2c679e6"},{"filename":"evals/nginx-multi-store-routing-config/task.md","content":"# nginx Configuration for Multi-Brand Magento Storefront\n\n## Problem/Feature Description\n\nA retail group operates a single Magento installation that needs to serve three distinct web properties from one server: a UK English storefront at `uk.fashiongroup.com`, a German-language storefront at `de.fashiongroup.com`, and a B2B wholesale portal at `b2b.fashiongroup.com`. The UK and German storefronts share the same customer database and order history — shoppers who registered on one can log in to the other — but the B2B portal serves an entirely separate corporate customer base with its own order management and payment terms.\n\nThe current nginx configuration only serves a single domain. The infrastructure team needs a production-ready nginx server block that routes each incoming request to the correct Magento context, with all environment variables set correctly so that Magento serves the right store without any changes to application code. The team has had previous issues where environment variables set in the wrong location weren't picked up by PHP-FPM, so correctness of placement is critical.\n\n## Output Specification\n\nProduce a single nginx configuration file named `magento-multi-store.conf` that can be dropped into `/etc/nginx/sites-available/`. The file should:\n\n- Handle all three domains listed above\n- Route each domain to the correct Magento context using appropriate environment variable values\n- Include a working PHP location block with FastCGI configuration passing the required Magento routing variables to PHP-FPM (assume socket path: `/var/run/php/php8.2-fpm.sock`)\n- Set the document root to `/var/www/magento/pub`\n\nWrite a brief `routing-notes.md` explaining the routing strategy chosen for each domain and why the B2B portal uses a different routing approach than the language storefronts.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":1829,"content_sha256":"ec31fdd7c38cfd1c653a5e9e103013cccfd93992090caaf4e712cdb01491bf40"},{"filename":"evals/php-scoped-config-and-product-assignment/criteria.json","content":"{\n \"context\": \"Tests whether the agent uses the correct Magento PHP APIs for reading and writing scoped configuration (WriterInterface, ScopeConfigInterface with ScopeInterface constants) and correctly assigns products to a website, including cache invalidation after config writes.\",\n \"type\": \"weighted_checklist\",\n \"checklist\": [\n {\n \"name\": \"WriterInterface for config writes\",\n \"max_score\": 12,\n \"description\": \"Config writes use Magento\\\\Framework\\\\App\\\\Config\\\\Storage\\\\WriterInterface (via $configWriter->save()) rather than direct database writes or other mechanisms\"\n },\n {\n \"name\": \"SCOPE_WEBSITE constant for website reads\",\n \"max_score\": 10,\n \"description\": \"Reading website-scoped config uses ScopeInterface::SCOPE_WEBSITE (from Magento\\\\Store\\\\Model\\\\ScopeInterface), not a raw string\"\n },\n {\n \"name\": \"SCOPE_STORE constant for store reads\",\n \"max_score\": 10,\n \"description\": \"Reading store-view-scoped config uses ScopeInterface::SCOPE_STORE (from Magento\\\\Store\\\\Model\\\\ScopeInterface), not a raw string\"\n },\n {\n \"name\": \"ScopeConfigInterface for reads\",\n \"max_score\": 10,\n \"description\": \"Config reads use Magento\\\\Framework\\\\App\\\\Config\\\\ScopeConfigInterface (via $scopeConfig->getValue()) rather than direct database or other access\"\n },\n {\n \"name\": \"Config cache flushed after write\",\n \"max_score\": 12,\n \"description\": \"After writing config values, the code cleans the config cache (e.g., CacheTypeListInterface::cleanType('config') or equivalent)\"\n },\n {\n \"name\": \"Product assigned via ProductResource\",\n \"max_score\": 12,\n \"description\": \"Product-to-website assignment uses ProductResource (Magento\\\\Catalog\\\\Model\\\\ResourceModel\\\\Product) and its websiteToProducts() method or equivalent API, not direct SQL\"\n },\n {\n \"name\": \"Website-specific pricing approach\",\n \"max_score\": 10,\n \"description\": \"Website-specific price setting references tier prices with website scope OR the catalog price scope setting, NOT a simple direct price attribute assignment\"\n },\n {\n \"name\": \"Dependency injection used\",\n \"max_score\": 8,\n \"description\": \"Classes receive dependencies (WriterInterface, ScopeConfigInterface, ProductResource, etc.) via constructor injection rather than using ObjectManager directly\"\n },\n {\n \"name\": \"StoreManagerInterface used for website lookup\",\n \"max_score\": 8,\n \"description\": \"Website or store objects are retrieved via StoreManagerInterface (e.g., getWebsite($code)) rather than hardcoded IDs\"\n },\n {\n \"name\": \"String codes for scope references\",\n \"max_score\": 8,\n \"description\": \"Scope references in config reads/writes use string codes (e.g., 'wholesale_site') not hardcoded numeric IDs\"\n }\n ]\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":2850,"content_sha256":"467e41decd0837debb2050dd6b110a8ae677cb2aa1d8c7a099ef546dfb688c36"},{"filename":"evals/php-scoped-config-and-product-assignment/task.md","content":"# PHP Data Setup Script for New Website Launch\n\n## Problem/Feature Description\n\nAn e-commerce platform running Adobe Commerce is launching a new wholesale website (`wholesale_site`) alongside the existing retail storefront. The development team needs a PHP setup script (a Magento data patch or standalone script) that handles the programmatic side of the website launch: making sure products from a specified list of SKUs are visible on the new wholesale website, setting website-level configuration values via the proper Magento API, and reading back configuration values at the correct scope to verify the setup.\n\nThe team has been burned before by config changes that appeared to take effect immediately but were actually still serving cached values hours later, so the setup script must handle cache invalidation. There's also a requirement to implement a helper class that other modules can use to safely read configuration at either website or store-view scope — the rest of the codebase should not have to deal with raw scope strings.\n\n## Output Specification\n\nProduce a PHP file (or set of files) that implements:\n\n1. **A configuration manager class** (`WebsiteConfigManager.php` or similar) that:\n - Can write a configuration value at a given scope and scope ID\n - Invalidates the config cache after writing\n - Can read a configuration value at website scope (given a website code)\n - Can read a configuration value at store view scope (given a store code)\n\n2. **A product assignment helper class** (`ProductWebsiteAssigner.php` or similar) that:\n - Accepts a product ID and website code and makes the product visible on that website\n - Includes a method that sets a website-specific price for a product\n\n3. **A setup script** (`setup.php` or a Magento DataPatch class) that uses the above helpers to:\n - Assign a hardcoded list of 3 product IDs (101, 102, 103) to `wholesale_site`\n - Set the base URL for `wholesale_site` to `https://wholesale.mystore.com/`\n - Read back and print the base URL at website scope to verify it was saved\n\nInclude inline comments in the code explaining the approach.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2127,"content_sha256":"6e72e197cff1f94d722d5930ca65e0d82346a188cedf063769543d8e457af57c"},{"filename":"tile.json","content":"{\n \"name\": \"finsi/magento-multi-store\",\n \"version\": \"0.1.0\",\n \"summary\": \"Multi-website, multi-store setup with shared catalogs and scoped config\",\n \"skills\": {\n \"magento-multi-store\": {\n \"path\": \"SKILL.md\"\n }\n }\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":231,"content_sha256":"fa5f376bc283879933b7f34ff0eaae5f2ec7ff53997917d89db3b49962f6d846"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Magento Multi-Store Setup","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Overview","type":"text"}]},{"type":"paragraph","content":[{"text":"Magento's multi-store architecture has three levels: Website → Store → Store View. A Website groups stores with a shared customer base and order flow. A Store (under a Website) has its own root category and URL structure. Store Views (under a Store) typically represent languages or locales. Configuration values can be set at Global, Website, or Store View scope — lower scopes override higher ones. Adobe Commerce (B2B) adds Shared Catalogs for per-company product/price visibility control.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to Use This Skill","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When running multiple brands or country-specific storefronts from a single Magento installation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When setting different base currencies, tax configurations, or payment methods per website","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When creating a B2B portal alongside a B2C store with different product visibility","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When implementing localized store views for multiple languages under the same product catalog","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When configuring separate checkout flows, shipping methods, or payment gateways per website","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When managing shared product catalog with website-specific pricing and visibility overrides","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Core Instructions","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Create the Website → Store → Store View hierarchy","type":"text","marks":[{"type":"strong"}]}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Note:","type":"text","marks":[{"type":"strong"}]},{"text":" Core Magento does not ship ","type":"text"},{"text":"bin/magento store:website:create","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"store:group:create","type":"text","marks":[{"type":"code_inline"}]},{"text":", or ","type":"text"},{"text":"store:store:create","type":"text","marks":[{"type":"code_inline"}]},{"text":" CLI commands. Create websites, stores, and store views either through ","type":"text"},{"text":"Admin → Stores → All Stores","type":"text","marks":[{"type":"strong"}]},{"text":" or programmatically in PHP (shown below). Some third-party modules add CLI equivalents, but they are not part of the core.","type":"text"}]}]},{"type":"paragraph","content":[{"text":"Via PHP programmatically (primary method):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"php"},"content":[{"text":"\u003c?php\n// Create website via DataObject\nuse Magento\\Store\\Model\\Website;\nuse Magento\\Store\\Model\\Group;\nuse Magento\\Store\\Model\\Store;\n\n$website = $objectManager->create(Website::class);\n$website->setCode('uk_site')\n ->setName('UK Website')\n ->setDefaultGroupId(0) // Set after creating group\n ->save();\n\n$storeGroup = $objectManager->create(Group::class);\n$storeGroup->setWebsiteId($website->getId())\n ->setName('UK Store')\n ->setRootCategoryId(3) // Your UK root category ID\n ->save();\n\n$storeView = $objectManager->create(Store::class);\n$storeView->setWebsiteId($website->getId())\n ->setGroupId($storeGroup->getId())\n ->setCode('uk_en')\n ->setName('UK English')\n ->setIsActive(1)\n ->save();","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Configure nginx for multi-website routing","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"nginx"},"content":[{"text":"# /etc/nginx/sites-available/magento-multi-store.conf\n\n# Map host to Magento store code (MAGE_RUN_CODE + MAGE_RUN_TYPE)\nmap $http_host $MAGE_RUN_CODE {\n hostnames;\n default \"\";\n www.mystore.com \"\"; # Default (global config)\n uk.mystore.com uk_en; # UK store view\n de.mystore.com de_de; # German store view\n b2b.mystore.com b2b_en; # B2B website\n}\n\nmap $http_host $MAGE_RUN_TYPE {\n hostnames;\n default \"\";\n www.mystore.com \"\";\n uk.mystore.com \"store\"; # Route to store view\n de.mystore.com \"store\";\n b2b.mystore.com \"website\"; # Route to website (different customer base)\n}\n\nserver {\n listen 443 ssl http2;\n server_name ~^(.+\\.)?mystore\\.com$;\n\n root /var/www/magento/pub;\n index index.php;\n\n location ~ \\.php$ {\n fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;\n fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE;\n fastcgi_param MAGE_RUN_TYPE $MAGE_RUN_TYPE;\n include fastcgi_params;\n }\n}","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Set scoped configuration values","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"Configuration can be set at global, website, or store view scope:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Set base URL per website\nbin/magento config:set --scope=websites --scope-code=uk_site web/secure/base_url \"https://uk.mystore.com/\"\nbin/magento config:set --scope=websites --scope-code=uk_site web/unsecure/base_url \"https://uk.mystore.com/\"\n\n# Set currency per website\nbin/magento config:set --scope=websites --scope-code=uk_site currency/options/base GBP\nbin/magento config:set --scope=websites --scope-code=uk_site currency/options/default GBP\nbin/magento config:set --scope=websites --scope-code=uk_site currency/options/allow \"GBP,EUR\"\n\n# Set locale per store view\nbin/magento config:set --scope=stores --scope-code=de_de general/locale/code de_DE\nbin/magento config:set --scope=stores --scope-code=de_de general/locale/timezone \"Europe/Berlin\"\n\n# Disable a payment method for specific website\nbin/magento config:set --scope=websites --scope-code=uk_site payment/checkmo/active 0","type":"text"}]},{"type":"paragraph","content":[{"text":"Programmatically in PHP:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"php"},"content":[{"text":"\u003c?php\nuse Magento\\Framework\\App\\Config\\Storage\\WriterInterface;\nuse Magento\\Store\\Model\\ScopeInterface;\n\nclass ScopeConfigManager\n{\n public function __construct(\n private readonly WriterInterface $configWriter,\n private readonly \\Magento\\Framework\\App\\Cache\\TypeListInterface $cacheTypeList\n ) {}\n\n public function setScopedValue(\n string $path,\n mixed $value,\n string $scope,\n int $scopeId\n ): void {\n $this->configWriter->save($path, $value, $scope, $scopeId);\n // Flush config cache after write\n $this->cacheTypeList->cleanType('config');\n }\n\n public function setWebsiteShippingOrigin(string $websiteCode, array $originData): void {\n $website = \\Magento\\Framework\\App\\ObjectManager::getInstance()\n ->create(\\Magento\\Store\\Model\\Website::class)\n ->load($websiteCode, 'code');\n\n $this->setScopedValue(\n 'shipping/origin/country_id',\n $originData['country'],\n ScopeInterface::SCOPE_WEBSITES,\n (int)$website->getId()\n );\n }\n}","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Manage website-specific product assignment and pricing","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"Products can be assigned to specific websites while sharing the global catalog:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"php"},"content":[{"text":"\u003c?php\n// Assign a product to specific websites\nuse Magento\\Catalog\\Model\\ResourceModel\\Product as ProductResource;\n\nclass ProductWebsiteAssignment\n{\n public function __construct(\n private readonly ProductResource $productResource,\n private readonly \\Magento\\Store\\Model\\StoreManagerInterface $storeManager\n ) {}\n\n public function assignProductToWebsite(int $productId, string $websiteCode): void {\n $website = $this->storeManager->getWebsite($websiteCode);\n $this->productResource->websiteToProducts([\n ['product_id' => $productId, 'website_id' => $website->getId()],\n ]);\n }\n\n public function setWebsitePrice(int $productId, string $websiteCode, float $price): void {\n // Use tier prices with website scope for website-specific pricing\n $tierPriceResource = \\Magento\\Framework\\App\\ObjectManager::getInstance()\n ->create(\\Magento\\Catalog\\Model\\ResourceModel\\Product\\Attribute\\Backend\\Tierprice::class);\n // Or use price scope: Admin → Config → Catalog → Price → Catalog Price Scope = Website\n }\n}","type":"text"}]},{"type":"paragraph","content":[{"text":"Enable website-scoped pricing:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"bin/magento config:set catalog/price/scope 1 # 0 = Global, 1 = Website\nbin/magento indexer:reindex catalog_product_price","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Configure Adobe Commerce B2B Shared Catalogs","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"Shared Catalogs (B2B feature) allow per-company product and pricing visibility:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"php"},"content":[{"text":"\u003c?php\n// Assign a company to a custom shared catalog\nuse Magento\\SharedCatalog\\Api\\SharedCatalogManagementInterface;\nuse Magento\\SharedCatalog\\Api\\Data\\SharedCatalogInterface;\n\nclass SharedCatalogManager\n{\n public function __construct(\n private readonly SharedCatalogManagementInterface $sharedCatalogManagement,\n private readonly \\Magento\\SharedCatalog\\Api\\SharedCatalogRepositoryInterface $catalogRepository,\n private readonly \\Magento\\Company\\Api\\CompanyRepositoryInterface $companyRepository\n ) {}\n\n public function assignCompanyToCatalog(int $companyId, int $sharedCatalogId): void {\n $sharedCatalog = $this->catalogRepository->get($sharedCatalogId);\n $company = $this->companyRepository->get($companyId);\n $company->getExtensionAttributes()->getQuoteConfig()?->setCustomerGroupId(\n $sharedCatalog->getCustomerGroupId()\n );\n $this->companyRepository->save($company);\n }\n}","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# CLI: Assign products to a shared catalog (by SKU list from CSV)\nbin/magento company:catalog:assign --catalog-id=2 --products-file=products.csv\n\n# Set catalog-specific pricing via import\nbin/magento import:start --entity=shared_catalog_product_price --behavior=add_update --import-file=prices.csv","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Examples","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Automated multi-website deployment configuration","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"php"},"content":[{"text":"\u003c?php\n// Console command to provision a new website from config array\nnamespace MyVendor\\MultiStore\\Console\\Command;\n\nuse Symfony\\Component\\Console\\Command\\Command;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\n\nclass ProvisionWebsiteCommand extends Command\n{\n protected function configure(): void\n {\n $this->setName('mystore:website:provision')\n ->setDescription('Provision a new website from config');\n }\n\n protected function execute(InputInterface $input, OutputInterface $output): int\n {\n $websites = [\n [\n 'code' => 'au_site',\n 'name' => 'Australia',\n 'domain' => 'au.mystore.com',\n 'currency' => 'AUD',\n 'locale' => 'en_AU',\n 'timezone' => 'Australia/Sydney',\n 'root_category_id' => 5,\n ],\n ];\n\n foreach ($websites as $config) {\n $output->writeln(\"Creating website: {$config['code']}\");\n // Execute creation commands...\n $this->createWebsite($config, $output);\n }\n\n return Command::SUCCESS;\n }\n\n private function createWebsite(array $config, OutputInterface $output): void\n {\n // Implementation: create Website → Group → StoreView → set config\n }\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Read scoped configuration in a custom module","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"php"},"content":[{"text":"\u003c?php\nuse Magento\\Framework\\App\\Config\\ScopeConfigInterface;\nuse Magento\\Store\\Model\\ScopeInterface;\n\nclass StoreAwareConfig\n{\n public function __construct(\n private readonly ScopeConfigInterface $scopeConfig\n ) {}\n\n public function getWebsiteConfig(string $path, ?string $websiteCode = null): mixed\n {\n return $this->scopeConfig->getValue(\n $path,\n ScopeInterface::SCOPE_WEBSITE,\n $websiteCode // null = current website\n );\n }\n\n public function getStoreConfig(string $path, ?string $storeCode = null): mixed\n {\n return $this->scopeConfig->getValue(\n $path,\n ScopeInterface::SCOPE_STORE,\n $storeCode // null = current store view\n );\n }\n\n // Usage\n public function getShippingOriginCountry(): string\n {\n return (string)$this->getStoreConfig('shipping/origin/country_id');\n }\n}","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Best Practices","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use store code routing (","type":"text","marks":[{"type":"strong"}]},{"text":"MAGE_RUN_TYPE=store","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":") for language variants","type":"text","marks":[{"type":"strong"}]},{"text":" and website routing (","type":"text"},{"text":"MAGE_RUN_TYPE=website","type":"text","marks":[{"type":"code_inline"}]},{"text":") only when you need separate customer bases, orders, and payment methods","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Enable website-scoped pricing","type":"text","marks":[{"type":"strong"}]},{"text":" before going live — switching from global to website scope later requires a full price index rebuild and may break existing catalog rules","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Set ","type":"text","marks":[{"type":"strong"}]},{"text":"MAGE_RUN_CODE","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" and ","type":"text","marks":[{"type":"strong"}]},{"text":"MAGE_RUN_TYPE","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" at the nginx/Apache level","type":"text","marks":[{"type":"strong"}]},{"text":", not in ","type":"text"},{"text":"index.php","type":"text","marks":[{"type":"code_inline"}]},{"text":" — this keeps routing config in the infrastructure layer and enables easier replication","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Test each website's checkout independently","type":"text","marks":[{"type":"strong"}]},{"text":" — payment gateways, tax classes, and shipping methods are all configurable per website; a working checkout on one website does not guarantee others work","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Flush configuration cache after every ","type":"text","marks":[{"type":"strong"}]},{"text":"config:set","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" — scoped config changes are cached; run ","type":"text"},{"text":"bin/magento cache:clean config","type":"text","marks":[{"type":"code_inline"}]},{"text":" after automated provisioning scripts","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use separate Redis databases per website in high-traffic setups","type":"text","marks":[{"type":"strong"}]},{"text":" — a slow reindex on one website can saturate shared cache storage and affect all websites","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Document the website/store/store-view ID mapping","type":"text","marks":[{"type":"strong"}]},{"text":" — IDs change between environments; use codes (","type":"text"},{"text":"uk_en","type":"text","marks":[{"type":"code_inline"}]},{"text":") not numeric IDs in all configuration scripts","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Common Pitfalls","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Problem","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Solution","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"New website shows global prices ignoring website config","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Enable website-scoped pricing: ","type":"text"},{"text":"bin/magento config:set catalog/price/scope 1","type":"text","marks":[{"type":"code_inline"}]},{"text":" then reindex ","type":"text"},{"text":"catalog_product_price","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"nginx ","type":"text"},{"text":"MAGE_RUN_CODE","type":"text","marks":[{"type":"code_inline"}]},{"text":" not passed to PHP","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Verify ","type":"text"},{"text":"fastcgi_param MAGE_RUN_CODE","type":"text","marks":[{"type":"code_inline"}]},{"text":" is inside the ","type":"text"},{"text":"location ~ \\.php$","type":"text","marks":[{"type":"code_inline"}]},{"text":" block and not outside it — a common placement mistake","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Customer from one website can log in to another","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Websites with ","type":"text"},{"text":"MAGE_RUN_TYPE=website","type":"text","marks":[{"type":"code_inline"}]},{"text":" share customer pools by default unless you enable customer account sharing scoped per website: ","type":"text"},{"text":"Admin → Config → Customer → Account Sharing","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Product visible on wrong website","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Check product's \"Product in Websites\" attribute in Admin → Catalog; products must be explicitly assigned to each website they should appear on","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Scoped config not taking effect","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Config values are cached — always run ","type":"text"},{"text":"bin/magento cache:clean config","type":"text","marks":[{"type":"code_inline"}]},{"text":" after changes; also verify the scope code spelling matches exactly","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"B2B shared catalog not filtering products","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"The customer must be assigned to a company with the correct catalog; guest and non-company customers see only the public shared catalog","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Related Skills","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"@magento-module-development","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"@magento-graphql","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"@magento-indexing-caching","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"@international-ecommerce","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"@b2b-commerce","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"magento-multi-store","risk":"safe","tags":["magento","multi-store","multi-website","store-scope","catalog","shared-catalog","b2b","scoped-config"],"tools":["claude-code","cursor","gemini-cli","copilot","codex-cli","kiro","opencode"],"author":"@skillopedia","source":{"stars":24,"repo_name":"awesome-ecommerce-skills","origin_url":"https://github.com/finsilabs/awesome-ecommerce-skills/blob/HEAD/skills/platform-magento/magento-multi-store/SKILL.md","repo_owner":"finsilabs","body_sha256":"5c3806d71b5cbab9bc7118b888588a88d28040cdc46f00ca4a4f70f56917e52b","cluster_key":"adf11e658b5b4fe16e87fe0179b846e31089f0f2a1d3f2f3b27f13bca058e91f","clean_bundle":{"format":"clean-skill-bundle-v1","source":"finsilabs/awesome-ecommerce-skills/skills/platform-magento/magento-multi-store/SKILL.md","attachments":[{"id":"bfc1bd55-80c0-5e98-ab9c-95c1fe739ec7","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/bfc1bd55-80c0-5e98-ab9c-95c1fe739ec7/attachment.json","path":"evals/cli-website-provisioning-script/criteria.json","size":2731,"sha256":"57e59a9a165207444c6e552746b81c8f2b37936013783d918ffac680c2574967","contentType":"application/json; charset=utf-8"},{"id":"8082f6f8-4ddc-554d-bdce-211fb88d7559","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/8082f6f8-4ddc-554d-bdce-211fb88d7559/attachment.md","path":"evals/cli-website-provisioning-script/task.md","size":2155,"sha256":"8af7d8da081fd869dbf6e50ff69213cdc948dfcf628f94500135ad2780ea2082","contentType":"text/markdown; charset=utf-8"},{"id":"0c93894e-d1d2-54a7-99bb-f6747ce3ebc3","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/0c93894e-d1d2-54a7-99bb-f6747ce3ebc3/attachment.json","path":"evals/nginx-multi-store-routing-config/criteria.json","size":2755,"sha256":"180257aaf7ec95ebcb8867a08f19578be9d907fe373df5b96cf46f35c2c679e6","contentType":"application/json; charset=utf-8"},{"id":"345bfd40-f4d9-53f4-95b2-d2e5be746aff","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/345bfd40-f4d9-53f4-95b2-d2e5be746aff/attachment.md","path":"evals/nginx-multi-store-routing-config/task.md","size":1829,"sha256":"ec31fdd7c38cfd1c653a5e9e103013cccfd93992090caaf4e712cdb01491bf40","contentType":"text/markdown; charset=utf-8"},{"id":"8cad0cba-6a7f-5eb5-8d69-efa3ab4ab3e7","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/8cad0cba-6a7f-5eb5-8d69-efa3ab4ab3e7/attachment.json","path":"evals/php-scoped-config-and-product-assignment/criteria.json","size":2850,"sha256":"467e41decd0837debb2050dd6b110a8ae677cb2aa1d8c7a099ef546dfb688c36","contentType":"application/json; charset=utf-8"},{"id":"aab81184-550a-51d8-9516-1bc0bb7a5b2d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/aab81184-550a-51d8-9516-1bc0bb7a5b2d/attachment.md","path":"evals/php-scoped-config-and-product-assignment/task.md","size":2127,"sha256":"6e72e197cff1f94d722d5930ca65e0d82346a188cedf063769543d8e457af57c","contentType":"text/markdown; charset=utf-8"},{"id":"5f1e9aa1-576d-55c8-91a0-8cabc0aec74d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/5f1e9aa1-576d-55c8-91a0-8cabc0aec74d/attachment.json","path":"tile.json","size":231,"sha256":"fa5f376bc283879933b7f34ff0eaae5f2ec7ff53997917d89db3b49962f6d846","contentType":"application/json; charset=utf-8"}],"bundle_sha256":"3d09204250d18af52c0dc27c3f968b8d4f9abccb9ac793db653fac3444711151","attachment_count":7,"text_attachments":7,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/platform-magento/magento-multi-store/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"web-development","category_label":"Web"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"web-development","triggers":["magento multi store","magento multiple websites","magento store scope","magento multi website setup","magento b2b shared catalog","adobe commerce multi store"],"platforms":["magento"],"date_added":"2026-03-12","difficulty":"advanced","import_tag":"clean-skills-v1","description":"Configure multiple websites and store views in Magento with shared or scoped catalogs, separate URL structures, and store-specific settings"}},"renderedAt":1782987490283}

Magento Multi-Store Setup Overview Magento's multi-store architecture has three levels: Website → Store → Store View. A Website groups stores with a shared customer base and order flow. A Store (under a Website) has its own root category and URL structure. Store Views (under a Store) typically represent languages or locales. Configuration values can be set at Global, Website, or Store View scope — lower scopes override higher ones. Adobe Commerce (B2B) adds Shared Catalogs for per-company product/price visibility control. When to Use This Skill - When running multiple brands or country-specif…