This guide describes how to configure your UPWARD server to run multiple PWA sites from a single backend, enabling you to serve different stores, regions, or languages with separate PWA experiences.
Overview
The UPWARD connector module (magento2-upward-connector) provides CLI tools to configure different PWA sites at the store, website, or global scope level. When you run the CLI commands, you add pwa_paths to the env.php file that specifies the paths to each PWA site's upward.yml configuration.
Configuration Scope Hierarchy
Path configurations follow the standard scope hierarchy, serving the most specific available site first:
store > website > default (global)
Step 1: Prepare Your Environment Variables
Create environment-specific configuration for each store you want to build.
Example .env files:
.env.french
MAGENTO_BACKEND_URL=https://french.yoursite.com
STORE_VIEW_CODE=french
.env.german
MAGENTO_BACKEND_URL=https://german.yoursite.com
STORE_VIEW_CODE=german
Step 2: Build PWA Bundles for Each Store
Build separate bundles for each storefront with their specific backend configurations.
Option A: Using Environment Files
cd /path/to/your/pwa-project
# Build French store
cp .env.french .env
yarn build
mv dist dist-french
# Build German store
cp .env.german .env
yarn build
mv dist dist-german
# Build default store
cp .env.default .env
yarn build
mv dist dist-default
Option B: Using Inline Environment Variables
# Build French store
MAGENTO_BACKEND_URL=https://french.yoursite.com yarn build
mv dist dist-french
# Build German store
MAGENTO_BACKEND_URL=https://german.yoursite.com yarn build
mv dist dist-german
# Build default store
MAGENTO_BACKEND_URL=https://yoursite.com yarn build
mv dist dist-default
Tip: You can automate this process by creating a build script that iterates through your store configurations.
Step 3: Deploy PWA Bundles
Copy your built PWA bundles to your server where they can be accessed by the UPWARD connector.
# Example deployment to server
scp -r dist-french user@server:/var/www/html/pwa-bundles/
scp -r dist-german user@server:/var/www/html/pwa-bundles/
scp -r dist-default user@server:/var/www/html/pwa-bundles/
Important: Ensure the web server user has read permissions on these directories.
Step 4: Configure UPWARD Paths
Use the UPWARD CLI to configure which bundle to serve for each store.
Set Default PWA Site
cd /path/to/magento/root
bin/magento pwa:upward:set --path /var/www/html/pwa-bundles/dist-default/upward.yml
Set Store-Specific PWA Sites
# French store
bin/magento pwa:upward:set \
--path /var/www/html/pwa-bundles/dist-french/upward.yml \
--scopeType store \
--scopeCode french
# German store
bin/magento pwa:upward:set \
--path /var/www/html/pwa-bundles/dist-german/upward.yml \
--scopeType store \
--scopeCode german
Set Website-Specific PWA Sites
bin/magento pwa:upward:set \
--path /var/www/html/pwa-bundles/dist-europe/upward.yml \
--scopeType website \
--scopeCode europe_site
Note: Paths can be relative (pwa/dist/upward.yml) or absolute (/var/www/html/pwa/dist/upward.yml).
Serving Non-PWA Storefronts
To serve a traditional storefront (non-PWA) for a specific store, use an empty string:
bin/magento pwa:upward:set --scopeType store --scopeCode traditional_store
Step 5: Verify Configuration
Check your configuration in the env.php file:
cat app/etc/env.php
You should see a pwa_path section like this:
'pwa_path' => [
'default' => [
'default' => '/var/www/html/pwa-bundles/dist-default/upward.yml'
],
'website' => [
'europe_site' => '/var/www/html/pwa-bundles/dist-europe/upward.yml'
],
'store' => [
'french' => '/var/www/html/pwa-bundles/dist-french/upward.yml',
'german' => '/var/www/html/pwa-bundles/dist-german/upward.yml'
]
]
Step 6: Test Your Setup
Clear cache and test each storefront:
bin/magento cache:clean
bin/magento cache:flush
Testing Checklist
- Access each store URL in your browser
- Verify the correct PWA bundle loads by checking the Network tab in DevTools
- Test store-specific features (language, currency, products)
- Verify service worker registration
- Test offline functionality
Creating Multiple Bundles - Complete Example
Here's a complete workflow for deploying French and German storefronts:
cd /path/to/your/pwa-project
# Build French bundle
MAGENTO_BACKEND_URL=https://french.mysite.com yarn build
mv dist dist-french
# Build German bundle
MAGENTO_BACKEND_URL=https://german.mysite.com yarn build
mv dist dist-german
# Copy bundles to server
scp -r dist-french user@server:/var/www/html/magento/pwa/
scp -r dist-german user@server:/var/www/html/magento/pwa/
# SSH to server and configure
ssh user@server
cd /var/www/html/magento
bin/magento pwa:upward:set \
--path ./pwa/dist-french/upward.yml \
--scopeType website \
--scopeCode fr
bin/magento pwa:upward:set \
--path ./pwa/dist-german/upward.yml \
--scopeType website \
--scopeCode de
bin/magento cache:flush
With this configuration, a single UPWARD server can process requests for multiple website bundles.
Troubleshooting
Wrong PWA Site Loads
Issue: The wrong bundle loads for a specific store.
Solution: Verify the scope hierarchy. Store-level configuration takes precedence over website and default.
cat app/etc/env.php | grep -A 20 "pwa_path"
404 Errors for Resources
Issue: Assets return 404 errors.
Solution: Verify file paths exist and have correct permissions.
ls -la /var/www/html/pwa-bundles/dist-french/upward.yml
sudo -u www-data cat /var/www/html/pwa-bundles/dist-french/upward.yml
Changes Not Reflected
Issue: Configuration changes don't take effect.
Solution: Clear the configuration cache.
bin/magento cache:clean config
bin/magento cache:flush
Wrong Backend URL in Bundle
Issue: Bundle connects to incorrect backend.
Solution: Verify environment variables and rebuild.
# Verify what's in the bundle
grep -r "yoursite.com" dist-french/
# Rebuild with correct URL
MAGENTO_BACKEND_URL=https://correct-backend.com yarn build