Configure Page Model API
In order to enable the Page Model API in the delivery tier, you need to configure the path of the Page Model JSON API on a Mount or SiteMapItem(s) to serve the initial SPA page.
If you choose to serve your SPA from a CDN or a node.js server directly, not from our delivery tier web application, then it is not needed to configure a Mount or SiteMapItem to serve the initial SPA page.
Configure the Page Model JSON API
Configuring the Page Model JSON API requires adding a single property, @hst:pagemodelapi, to a virtual host (hst:virtualhost) or mount (hst:mount) configuration node. The value of the property will be the path on which the Page Model JSON API child mount becomes available. For example, if the @hst:pagemodelapi property is configured like the following on a mount (hst:mount) configuration node (for mount path like /, /myapp, etc.), then the Page Model JSON API mount becomes available automatically at the configured mount path + / + resourceapi. e.g, /resourceapi, /myapp/resourceapi, etc. You don't need to configure the resourceapi mount underneath explicitly.
hst:pagemodelapi = resourceapi
If the @hst:pagemodelapi property is configured on a virtual host (hst:virtualhost) configuration node, all the descendant mounts under the virtual host will get the resourceapi child mount automatically.
Note that the Page Model JSON API child mount becomes available only for the mounts that are mapped (@hst:ismapped=true) and associated with a specific Channel.
Configure SPA Site Mount
When you serve SPAs through our delivery tier web application, not from node.js or CDN directly, you should configure an SPA Site Mount.
Suppose you have a channel which is mapped to a mount (e.g, hst:root or myapp). You can make the mount an SPA Site Mount as in the following example:
/hst:hst/hst:hosts/dev-localhost/localhost/hst:root/myapp: jcr:primaryType: hst:mount hst:mountpoint: /hst:hst/hst:sites/myapp hst:namedpipeline: SpaSitePipeline hst:pagemodelapi: resourceapi
First, set @hst:namedpipeline property to SpaSitePipeline for your Single Page Application. A mount with @hst:namedpipeline=SpaSitePipeline will render only the root HST component for a page URL (e.g, /, /news, /news/news1.html, etc.). The resolved root HST component and its rendering template (ftl or jsp) should serve the HTML that fetches your SPA. For example, it could serve something like the following:
Afterward, your SPA is able to invoke Page Model JSON API on the /resourceapi child mount (e.g, /resourceapi, /resourceapi/news, /resourceapi/news/news1.html, etc.), as configured by the @hst:pagemodelapi property.
You can also change the value of @hst:pagemodelapi property from the default value (resourceapi) to something else to change the endpoint of Page Model JSON API, but in that case make sure your Single Page Application uses the new Page Model API endpoint.
Configure SPA Channel
There is no difference in configuring an SPA Channel from other channels. Please follow the Experience manager documentation. However, please note that the Experienace Manager SPA Integration feature is available only to Bloomreach Experience Manager customers.
Configure CORS Response Headers
You may want SPAs on an external server to consume JSON resources from the Page Model JSON API. For example, you could run an external node.js server for SPAs which needs to consume JSON resources from Page Model JSON API residing in the HST delivery web application. As those reside in different domains, the appropriate CORS response headers must be set by the HST delivery tier web application.
HST allows configuring additional custom response headers - including CORS headers - at virtual host, mount, or even sitemap item level, by setting the @hst:responseheaders (string multiple) property. This way you can set the Access-Control-Allow-Origin response header to a single host or to '*' to allow any origin.
Alternatively, the @hst:allowedorigins property allows whitelisting multiple origins at virtual host level. This way, if a cross-origin request is made from a whitelisted origin, the Access-Control-Allow-Origin response header is automatically set to that origin.
As a guideline, consider the table below listing four typical use cases and their required CORS configurations:
|Page Model API Use Case||CORS Configuration|
|Do not allow any cross-origin Page Model API requests||Default, no additional configuration needed.|
|Allow Page Model API requests from any origin||hst:responseheaders: ["Access-Control-Allow-Origin: *"]|
|Allow Page Model API request from one specific origin||hst:responseheaders: ["Access-Control-Allow-Origin: http://www.example.com"]|
|Allow Page Model API requests from one or more whitelisted origins||hst:allowedorigins: ["http://www.example.org", "http://www.example.com"]|
- For cross-origin Page Model API requests from an allowed origin, the Access-Control-Allow-Credentials response header is always set (to its only valid value true).
- If the Access-Control-Allow-Origin response header is defined in the @hst:responseheaders property, the @hst:allowedorigins property is ignored.
- The hst:allowedorigins property is available since Bloomreach Experience Manager 14.1.0. If your implementation project is on 14.0, you must upgrade to 14.1 in order to use hst:allowedorigins.
Configure Internal Link URL Prefix
In some use cases, for example when a client is accessing the Page Model API through a reverse proxy, the internal links included in the response need to be rewritten to be accessible to the client.
/hst:myproject/hst:hosts/dev-localhost/localhost/hst:root: jcr:primaryType: hst:mount hst:homepage: root hst:mountpoint: /hst:myproject/hst:sites/myproject hst:pagemodelapi: resourceapi hst:linkurlprefix: https://www.example.org/foo
In the example above, all fully qualified links served from the hst:root mount (or its submounts, if any) will be prefixed with the configured prefix https://www.example.org/foo.
Please note that an hst:linkurlprefix configured on a submount does not apply to binary links because those are always served from the root mount.