ScandiPWA is traditionally compiled in one of 2 modes: Magento and storefront mode. When optimizing performance, ideally, we want to server production-like build, but with HTTP2 and compression enabled, to match the future deployment environment. To achieve this, we need to setup an express server.

To setup the express server, you will need to:

1. Install the dependencies

From ScandiPWA application root, install the dependencies:

yarn add express compression http-proxy-middleware spdy # using Yarn
npm i express compression http-proxy-middleware spdy # using NPM

2. Generate SSL certificates

From ScandiPWA application root, generate SSL certificates (no need to add them to trusted):

openssl req -x509 -newkey rsa:2048 -nodes -sha256 -keyout privateKey.key -out certificate.crt

3. Create a server configuration

In ScandiPWA application root, create a server.js file:

/* eslint-disable @scandipwa/scandipwa-guidelines/export-level-one, no-console */

const express = require('express');
const compression = require('compression');
const { createProxyMiddleware } = require('http-proxy-middleware');
const fs = require('fs');
const path = require('path');
const spdy = require('spdy');

const PORT = 8080;
const PROXY_TO_URL = '<https://my-real-production-server.com/>';
const PATH_TO_BUILD_FOLDER = './build'

const app = express();

app.use(compression());

app.use(express.static(PATH_TO_BUILD_FOLDER));

app.use('/graphql', createProxyMiddleware({
    target: PROXY_TO_URL,
    changeOrigin: true
}));

app.use('/media', createProxyMiddleware({
    target: PROXY_TO_URL,
    changeOrigin: true
}));

app.get('/*', (req, res) => {
    res.sendFile(path.join(__dirname, PATH_TO_BUILD_FOLDER + '/index.html'));
});

const options = {
    key: fs.readFileSync(path.join(__dirname, '/privateKey.key')),
    cert: fs.readFileSync(path.join(__dirname, '/certificate.crt'))
};

spdy.createServer(options, app).listen(PORT, (error) => {
    if (error) {
        console.error(error);
        process.exit(1);
    }

    console.log(`HTTP/2 server listening on port: ${PORT}`);
});

Replace the constants with desired values:

const PORT = 8080;
const PROXY_TO_URL = '<https://my-real-production-server.com/>';

4. Build the application

From ScandiPWA application root, run build the application in storefront mode:

yarn build # using Yarn
npm run build # using NPM

5. Start the server

From ScandiPWA application root, run the express server:

node server.js

<aside> 🧠 After making changes to code, build the app & start the server using a single command:

yarn build && node server.js # using Yarn
npm run build && node server.js # using NPM

</aside>

6. Trust your local server

Open Google Chrome, visit the https://localhost:<PORT> where port is as declared in the previous step. In our case, https://localhost:8080. You will see the warning, suspend it.

Click Advanced button, click Proceed to localhost (unsafe). You should see the website appear.

Untitled

<aside> ➡️ Use https instead of http

</aside>

7. Set correct window.contentConfiguration

<aside> 🧠 ScandiPWA has a feature of content customization. It allows users to define custom CSS colors for elements, use custom CMS blocks in different locations. Read more in the official ScandiPWA user guide.

</aside>

To make sure the configurable content matches the original website, the following actions must be taken:

  1. Visit the original website (targeted as proxy), open the console
  2. Type in window.contentConfiguration , press Enter
  3. Right-click on the console logged object Copy object
  4. Override the public/index.html (for development)
  5. Update (or add if missing) the copied definition of window.contentConfiguration to the newly created file