SSRServer(options)

To create an SSR Server, project code should import this class and create an instance of it. To implement hooks like requestHook or responseHook, extend this class and override those hook methods as needed.

Constructor

new SSRServer(options)

Create an SSR (Server-Side Rendering) Server.

Project code can either create an instance of this class, or extend this class to provide an implementation of the requestHook and/or responseHook methods.

Parameters:
Name Type Description
options Object
Properties
Name Type Attributes Default Description
allowedUrls Array.<RegExp> <optional>
[]

a list of path regexes (including bundle assets and file:// URLs) for URLs to load resources from

buildDir String <optional>

The build directory path, either as an absolute path, or relative to the current working directory. Defaults to 'build'.

defaultCacheTimeSeconds Number <optional>
600

The cache time for rendered pages and assets (not used in local development mode).

errorCacheTimeSeconds Number <optional>
60

The cache time for error pages (not used in local development mode).

faviconPath String

The path to the favicon.ico file, either as an absolute path, or relative to the build directory. If this value is not supplied, requests for a favicon will return a 404 and log a warning to the console.

fetchAgents Object <optional>

An optional object which can define, for one or both of the 'http' and 'https' protocols, an Agent (http.Agent or https.Agent) object that will be used for fetches under that protocol

loadCaptureJS Boolean <optional>
true

true to have capture.js loaded for the PWA when rendering, false to not load JQuery. This is true to simplify migration from a PWA to a UPWA. A new UPWA project would generally pass false for this value. Setting this will make capture.js available server-side and client-side. Also see loadJQuery, which may override this option.

loadJQuery Boolean <optional>
true

true to have JQuery loaded for the PWA when rendering, false to not load JQuery. Setting this will make JQuery available server-side and client-side. It will also make capture.js available, because some parts of the SDK assume that if JQuery is present, capture.js is also present.

mainFilename String <optional>
'main.js'

the name of the main PWA file, relative to the build directory.

manifestPath String <optional>
'static/manifest.json'

the name of the manifest file, relative to the build directory.

mobify Object

The 'mobify' object from the project's package.json file, containing the SSR parameters.

optimizeCSS Boolean <optional>
false

set true to have the SSR Server generate minimal inline CSS for the rendered page, false to use the main stylesheet. CSS opimization works well for small stylesheets, but may slow down server-side rendering too much with large stylesheets.

port Number <optional>
3443

the localhost port on which the local development SSR server listens.

protocol String <optional>
'https'

the protocol on which the development SSR server listens.

routes Array.<RegExp>

an Array of regular expressions for the routes supported by the PWA. Requests for paths that match any of the routes cause rendering of a page. Routes start with a '/'.

sslFilePath String

the absolute path to a PEM format certificate file to be used by the local development server. This should contain both the certificate and the private key.

ssrLoaderFilename String <optional>
'ssr-loader.js'

the name of the SSR loader file, relative to the build directory.

ssrLoaderScripts Array.<String> <optional>
[]

a list of paths, relative to the build directory, of scripts that the SSR Loader should load client-side. Commonly used to load third-party scripts included in the project, such as analytics scripts.

stylesheetFilename String <optional>
'main.css'

the name of the main stylesheet, relative to the build directory.

supportedBrowsers Array.<Object> <optional>

a list of supported browser objects, either RegExp or browser objects with: name (String), version (Integer) and mobile (optional, Boolean, defaults to false) keys e.g. [{name: 'chrome', version: 53, mobile: true}, /^(?!.*(opr|opera|edge)).*chrome/(51|52.1.2)/]

unsupportedBrowserRedirect String <optional>
''

a relative or absolute URL to which the client should be redirected if the browser is not supported, used in window.location.replace(). If the URL is not provided, the browser detection script will not be loaded.

vendorFilename String <optional>
'vendor.js'

the name of the vendor file, relative to the build directory.

Classes

SSRServer

Members

applicationCache

Get a reference to a Cache instance that can be used by methods of this instance to store and retrieve data.

The cache instance is created on-demand; once created it exists for the lifetime of the SSRServer instance.

In the local development server, the cache contents persist until the server process exits (so it is empty when the server starts up). In a deployed SSR server, the cache persists indefinitely and is shared by all executing SSR Server instances. The cache is not cleared when a new bundle is published.

persistentCache

A backwards compatibility property that returns the current applicationCache. You should use the applicationCache property directly. See the docs for the applicationCache property for more information on the cache.

Deprecated:
  • Yes

Methods

(static) generateCacheKey(request, optionsopt) → {String}

Use properties of the request, such as URL and querystring, to generate a cache key string suitable for passing to sendResponseFromCache or storeResponseInCache.

This method is provided as a convenience: you do not have to use it, but it should cover the most common use cases. It is the default cache key generator used by sendResponseFromCache and storeResponseInCache. If you override the cache key function in the options for storeResponseInCache, you may call this function and then further modify the returned key.

The cache key is based on the request's path (case-independent) and querystring (case-dependent). The order of parameters in the querystring is important: if the order changes, the cache key changes. This is done because the order of query parameters is important for some systems.

To allow for simple extension of the default algorithm, the optional 'options.extras' parameter may be used to pass an array of strings that will also be used (in the order they are passed) to build the key. Undefined values are allowed in the extras array.

By default, the key generation does NOT consider the Accept, Accept-Charset or Accept-Language request header values. If it's appropriate to include these, the caller should add their values (or values based on them) to the options.extras array.

Requests that come to a deployed SSR Server contain headers that identify the device type. By default, this method generates different cache keys for different device types (effectively, the values of the headers used by getBrowserSize are included in 'options.extras'). To suppress this, pass true for options.ignoreDeviceType

By default, method will generate different cache keys for requests with different request classes (effectively, the value of the request-class string is included in 'extras'). To suppress this, pass true for options.ignoreRequestClass

Parameters:
Name Type Attributes Description
request IncomingMessage

the request to generate the key for.

options Object <optional>

values that affect the cache key generation.

Properties
Name Type Attributes Description
extras Array.<(String|undefined)> <optional>

extra string values to be included in the key.

ignoreDeviceType Boolean <optional>

set this to true to suppress automatic variation of the key by device type.

ignoreRequestClass Boolean <optional>

set this to true to suppress automatic variation of the key by request class.

Returns:

the generated key.

Type
String

(static) get(server)

Lambda event handler. When called with a server instance, this returns a 'get' function that supports AWS Lambda integration using that server instance.

The result of calling this function with an SSRServer instance should be exported by the ssr.js file of a project.

Parameters:
Name Type Description
server SSRServer

the SSR Server instance

Example
export const get = SSRServer.get(server)

cacheResponseWhenDone(request, response, expirationopt, keyopt, namespaceopt, shouldCacheResponseopt)

Configure a response so that it will be cached when it has been sent. Caching ExpressJS responses requires intercepting of all the header and body setting calls on it, which may occur at any point in the response lifecycle, so this call must be made before the response is generated.

If no key is provided, it's generated by SSRServer.generateCacheKey. Project code may call generateCacheKey with extra options to affect the key, or may use custom key generation logic. If code has previously called getResponseFromCache, the key and namespace are available as properties on the CachedResponse instance returned from that method.

When caching response, the cache expiration time is set by the expiration parameter. The cache expiration time may be different to the response expiration time as set by the cache-control header. See the documentation for the 'expiration' parameter for details.

Parameters:
Name Type Attributes Description
request express.request
response express.response
expiration Number <optional>

the number of seconds that a cached response should persist in the cache. If this is not provided, then the expiration time is taken from the Cache-Control header; the s-maxage value is used if available, then the max-age value. If no value can be found in the Cache-Control header, the default expiration time is one week.

key String <optional>

the key to use - if this is not supplied, SSRServer.generateCacheKey will be called to derive the key.

namespace String | undefined <optional>

the cache namespace to use.

shouldCacheResponse function <optional>

an optional callback that is passed a Response after it has been sent but immediately before it is stored in the cache, and can control whether or not caching actually takes place. The function takes the request and response as parameters and should return true if the response should be cached, false if not.

getResponseFromCache(request, response, keyopt, namespaceopt) → {Promise.<CachedResponse>}

Look up a cached response for the given request in the persistent cache and return a CachedResponse that represents what was found.

This method would generally be called in the requestHook. The caller should check the result of resolving the Promise returned by this method. The returned object's 'found' property is true if a response was found, 'false' if no response was found.

The CachedResponse instance returned has details of any cached response found, and project code can then choose whether to send it or not. For example, the headers may be checked. To send that cached response, call sendCachedResponse with it.

If there is no cached response found, or the project code does not choose to send it, then the code can also choose whether the response generated by the server should be cached. If so, it should call cacheResponseWhenDone.

If no key is provided, it's generated by SSRServer.generateCacheKey. Project code may call generateCacheKey with extra options to affect the key, or may use custom key generation logic.

By default, all cache entries occupy the same namespace, so responses cached for a given URL/querystring/headers by one version of the UPWA may be retrieved and used by other, later versions. If this is not the required behaviour, the options parameter may be used to pass a 'namespace' value. The same cache key may be used in different namespaces to cache different responses. For example, passing the bundle id as the namespace will result in each publish bundle starting with a cache that is effectively per-bundle. The namespace value may be any string, or an array of strings.

Parameters:
Name Type Attributes Description
request express.request
response express.response
key String <optional>

the key to use - if this is not supplied, SSRServer.generateCacheKey will be called to derive the key.

namespace String | undefined <optional>

the cache namespace to use.

Returns:

resolves to a CachedResponse that represents the result of the cache lookup.

Type
Promise.<CachedResponse>

requestHook(request, response, next, options)

May be overridden in a derived class to implement a hook that's called after the basic built-in routes but before the UPWA is passed the route to handle. The route is available via request.path.

This is an ExpressJS middleware function (see http://expressjs.com/en/guide/writing-middleware.html). Unlike the other SSR Server routes, it can handle GET, POST and other standard HTTP methods. The request method is available via request.method (as an upper-case string). The request path is available via request.originalUrl and will start with a '/'.

The requestHook is never called for the root path ('/').

Requests handled by the requestHook will never contain cookies, and any Set-Cookie headers added to responses will be stripped off before they are sent. This is because all requests handled by the SSR Server should be as cacheable as possible, and responses that are affected by cookies are not generally cacheable.

For POST requests, the body of the request may be text (text/plain), JSON (application/json) or form data (application/x-www-form-urlencoded).

It's important to note that the requestHook does NOT execute in the browser-like environment provided for the UPWA code. It's running under NodeJS, so there is no 'window' object, no JQuery and no DOM. Because the hook code may need to make external HTTP requests, an implementation of fetch is provided in the options object passed to the function.

To let the route be handled by the UPWA, call next(). To handle a route, generate a response and do not call next().

It's okay for the requestHook to delay sending the response (for example, by waiting on a Promise before sending).

Parameters:
Name Type Description
request Request

the ExpressJS Request - this is the request that the SSR Server is currently handling.

response Response

the ExpressJS Response - this is the response to the current event. If your requestHook chooses to handle the request, use this object to build the response.

next function

pass control to the next handler

options Object

contains reference data for the function

Properties
Name Type Attributes Description
local Boolean

true if running in a local development server, false if running in a remote SSR Server

bundleId String

the published bundle id number, or 'development' if running in the local development server

deployId String

the id of the deploy, or '0' if running in the local development server

deployTarget String

the id of the target on which a deployed SSR server is running, or 'local' if running in the local development server

fetch function

the same 'fetch' function used by the UPWA code (which supports fetches to proxy paths)

appHostname String

a string, the hostname for this SSR Server (hostname, port)

appOrigin String

a string, the origin for this SSR Server (protocol, hostname, port)

proxyConfigs Array

the proxyConfigs array describing the proxy configuration - the same array returned by getProxyConfigs from universal-utils

requestClass String <optional>

the request class, as set by the request processor. Will be undefined if this request has no class set.

respondFromBundle(options)

Provided for use by requestHook overrides.

Call this to return a response that is a redirect to a bundle asset. Be careful with response caching - 301 responses can be cached. You can call response.set to set the 'Cache-Control' header before calling this function.

This function returns a Promise that resolves when the response has been sent. The caller does not need to wait on this Promise.

Parameters:
Name Type Description
options Object
Properties
Name Type Attributes Description
request Request

the ExpressJS request object

response Response

the ExpressJS response object

path String <optional>

the path to the bundle asset (relative to the bundle root/build directory). If this is falsy, then request.path is used (i.e. '/robots.txt' would be the path for 'robots.txt' at the top level of the build directory).

redirect Number <optional>

a 301 or 302 status code, which will be used to respond with a redirect to the bundle asset.

responseHook(request, response, options)

May be overridden in a derived class to implement a hook that's called after the HTML page is ready and default header values have been set.

This function operates like ExpressJS middleware, but when it is called, the response is already in progress. You can set/change headers and the response status code using the response object, but you should not send data or call end() on it.

Note that the responseHook does NOT execute in the browser-like environment provided for the UPWA code. It runs under NodeJS, and there is no 'window' object.

Parameters:
Name Type Description
request Request

the ExpressJS Request

response Response

the ExpressJS Response

options Object

contains the 'local' and 'isErrorResponse' flags

Properties
Name Type Attributes Description
local Boolean

true if running in a local development server, false if running in a remote SSR Server

bundleId String

the published bundle id number, or 'development' if running in the local development server

deployId String

the id of the deploy, or '0' if running in the local development server

deployTarget String

the id of the target on which a deployed SSR server is running, or 'local' if running in the local development server

isErrorResponse: Boolean

true if the page that is being returned is an error page

appHostname String

a string, the hostname for this SSR Server (hostname, port)

appOrigin String

a string, the origin for this SSR Server (protocol, hostname, port)

requestClass String <optional>

the request class, as set by the request processor. Will be undefined if this request has no request class set.

sendCachedResponse(cached)

Given a CachedResponse that represents a response from the cache, send it. Once this method has been called, the response is sent and can no longer be modified. If this method is called from the requestHook, the caller should return, and should not call next()

Parameters:
Name Type Description
cached CachedResponse

the cached response to send