A UPWA is a Universal PWA. The “Universal” part means that it runs across many devices: phones, tablets and desktops.
The Mobify Platform supports building UPWAs using the same components and developer workflow used for PWAs. UPWAs are built using React to render HTML, and Redux to store application state.
We’ll assume that you’re familiar with how PWAs work on the Mobify Platform:
- The PWA renders HTML using React components
- The HTML rendered depends on the route (the path of the URL for the page that’s shown in the browser)
- Data is pulled from a backend server (sometimes a webserver that returns HTML, sometimes an ecommerce backend that provides a REST API)
However, there are some fundamental concepts that are new to UPWAs. To explain these concepts, we’ll use this scenario:
- WidgetCorp, Inc is developing a new UPWA for their existing
- They have an ecommerce backend, which is available at
api.widgetcorp.com, from which the UPWA will take data to render the pages.
The SDK documentation also contains a reference section on UPWAs.
Server-side rendering (usually abbreviated to SSR) uses the UPWA code to generate the HTML returned by a server to a client.
Currently, WidgetCorp runs a webserver, and the hostname
to that webserver. When a device requests a URL from the webserver, the webserver
fetches data from the backend server, uses it to render an HTML page
for that URL and returns the page to the device.
When the UPWA is launched,
www.widgetcorp.com will point instead to an
SSR server (code that runs on the Mobify Platform). When a device
requests a URL from the SSR Server, it will do the following:
- Run the UPWA code, setting the route to match the URL
- Allow the UPWA to render HTML, using React, with state kept in the Redux store. The UPWA is able to fetch data from the backend server.
- Once rendering is complete, return an HTML page to the device that contains:
- The HTML that the UPWA rendered
- A copy of the state from the Redux store
<script>element that will load the UPWA on the browser
When the page is received by the device, it can immediately display the HTML while the UPWA loads, which allows a fast startup (faster than a PWA).
An important point to note is that the UPWA is run in two different places:
- Server-side, in the SSR Server
- Client-side, in the browser
The WidgetCorp website contains assets (scripts or other files) and handles POST requests that the UPWA will use when rendering. As an example, we’ll consider the following:
www.widgetcorp.com/assets/logo.pngis the corporate logo image. The UPWA will need to use this image in rendered HTML.
www.widgetcorp.com/tracking.jsis a analytics script that provides tracking of browser usage. The UPWA-rendered pages should load this script.
www.widgetcorp.com/loginis a URL that the web server provides, which handles checking of credentials sent in a POST, and sets a login cookie in the response. The response also contains CORS headers to restrict access.
When the UPWA is launched,
www.widgetcorp.com will no longer point at
the WidgetCorp webserver, and so these URLs will no longer work. To fix this,
the UPWA can use the proxying support built into the Mobify Platform.
Here’s how we can set that up:
- Add a new hostname
server.widgetcorp.comthat will continue to point to the WidgetsCorp webserver even when
www.widgetcorp.comchanges to point to the SSR Server. We call
server.widgetcorp.comthe target hostname for proxying.
- Configure proxying so that requests to
www.widgetcorp.com/mobify/proxy/base/will be automatically forwarded to the
server.widgetcorp.comserver. We call
www.widgetcorp.comthe application hostname for proxying.
Once this is set up, a request for
will be routed to
server.widgetcorp.com/assets/logo.png. The UPWA can then
render Image components that use the
/mobify/proxy/base path, and the images
will be fetched from the WidgetCorp webserver.
Similarly, to load the script
www.widgetcorp.com/tracking.js, the UPWA
would use the path
Finally, the UPWA can use the
/login URL via a POST to
request and response are processed so that headers such as
Access-Control-Allow-Origin are modified, to allow use of the URL
despite the POST being made to
www.widgetcorp.com instead of
Proxying has a number of advantages:
- It’s fully transparent and rewrites the request and response so that POSTs, PUTs and GETs work via the proxy.
- The browser can make all requests to
www.widgetcorp.com(the application hostname), avoiding CORS issues.
- It supports multiple proxy setups, so more than one target host can be
proxied (each has a separate path under
- Because the proxying paths are available on the application hostname, browsers can re-use existing connections to that hostname, resulting in improved performance.
Proxying is described in more detail here.
UPWAs using the Mobify Platform, like PWAs, are made up of files that
are deployed as part of a bundle.
The SSR Server makes bundle files available under the path
Each bundle has a bundle id (a number unique within the project), and the full path
used to refer to bundle files is
/mobify/bundle/<bundle-id>/ (when running
the local development SSR server,
the path will be
/mobify/bundle/development/). These paths are relative
to whatever hostname is being used to address the SSR server.
When a new bundle is deployed, browsers that load the new version of the UPWA will use the correct path for assets within that new bundle, while existing versions of the UPWA will use the correct paths for files in their bundles.
Because the bundle files are loaded via a path on the application hostname, browsers can re-use existing connections to that hostname, resulting in improved performance.
The UPWA Lifecycle #
There is a key difference between UPWAs and PWAs. UPWAs run on the SSR server and then again in the browser. PWAs only ever run and render in the browser.
When a UPWA is running on the SSR server, we say that it is running server-side. When a UPWA is running in the browser, we say that it is running client-side (the browser is the “client”).
A UPWA therefore has several stages of execution, and we use the term UPWA Lifecycle to refer to these.
The lifecycle can be summarized:
- A device makes a request to the SSR server for a page
- The SSR server runs the UPWA code server-side to generate the HTML
- The HTML is returned to the device which displays it
- The device then loads the UPWA code into the browser
- The UPWA starts up and “hydrates”) by rendering the same HTML that was sent from the server, so that React now owns that HTML
- The UPWA completes hydration and runs client-side. The user can now navigate to other pages, which are rendered by the UPWA running client-side.
The full lifecycle, including an explanation of how UPWA code can identify the lifecycle stages, plus what should and should not be rendered in each stage, is explained in detail here.