SPA Integration Troubleshooting

This page is related to libraries @bloomreach/spa-sdk and @bloomreach/react-sdk. If you are using bloomreach-experience-react-sdk with the CMS version 14, please see this troubleshooting page.

This page provides information about common problems that you may run into while integrating Single-Page Applications (SPA) with Bloomreach Experience Manager. Each section consists of a problem explanation, potential reasons causing the problem, and the solution that may help to solve the problem.

Overlays are not showing up

Problem

Overlays and content management buttons are not visible even when overlay controls are toggled on (see Image 1).

Overlays are not showing up

Image 1. Overlays are not showing up

Reason

The potential reason for this behavior can be one of the following:

  1. Wrong preview base path in the SPA using @bloomreach/react-sdk or @bloomreach/spa-sdk.
    It can be that the options.preview.spaBaseUrl does not match with the SPA URL in the preview.

  2. Outdated reverse proxy-based setup is being used along with an updated SPA configuration.

  3. Outdated Bloomreach Experience Manager version.
    @bloomreach/react-sdk or @bloomreach/spa-sdk support only Bloomreach Experience Manager version 14 and above.

  4. Incompatible plugin version.
    The page model addon with a different version than the Bloomreach Experience Manager version can cause not working preview mode.

  5. Experience manager functionality (drag and drop components, +component configuration, content editing through the visual editor) for SPA is only supported in the enterprise version.

  6. The CMS (brXM) and Site (Delivery API) applications are served from different hosts but the SPA does not set the origin parameter accordingly.

Solution

  1. In the reverse proxy-based setup prior to brXM 14.2, configure options.preview.spaBaseUrl to contain the correct base path and preview query parameter:

    const page = await initialize({
      // ...
      options: {
        live: {
          cmsBaseUrl: 'http://localhost:8080/site',
          spaBaseUrl: '',
        },
        preview: {
          cmsBaseUrl: 'http://localhost:8080/site/_cmsinternal',
          spaBaseUrl: '/site/_cmsinternal?bloomreach-preview=true',
        },
      },
    });
    

    Or if you use @bloomreach/react-sdk:

    REACT_APP_LIVE_BR_BASE_URL=http://localhost:9080/site
    REACT_APP_LIVE_SPA_BASE_URL=
    REACT_APP_PREVIEW_BR_BASE_URL=http://localhost:9080/site/_cmsinternal
    REACT_APP_PREVIEW_SPA_BASE_URL=/site/_cmsinternal?bloomreach-preview=true
    
  2. In the setup without a reverse proxy as supported from brXM 14.2, configure cmsBaseUrl and spaBaseUrl to contain the correct brXM base URL and the base path accordingly:

    const page = await initialize({
      cmsBaseUrl: 'http://localhost:8080/site',
      spaBaseUrl: '',
    });
    

    Or if you use @bloomreach/react-sdk:

    REACT_APP_CMS_BASE_URL=http://localhost:9080/site
    REACT_APP_SPA_BASE_URL=
    
  3. Make sure you use Bloomreach Experience Manager version 14+.

  4. Make sure that you have hippo-enterprise-package-site-dependencies with the same version as hippo-cms.

  5. Make sure you are running the enterprise version of Bloomreach Experience Manager.

  6. Make sure that your SPA sets the origin parameter value to the domain of the CMS from which the SPA is loaded for preview in the Experience manager. Refer to the SPA SDK documentation for details.

The SPA is not showing up

Problem

Some pages of the SPA are not visible in the Experience manager (see Image 2) or displaying Server Error (see Image 3), but at the same time, these pages are accessible outside the CMS.

The Experience manager displays a blank page

Image 2. The Experience manager displays a blank page

The Experience manager displays “Server Error”

Image 3. The Experience manager displays “Server Error”

Reason

The potential reason for this behavior is related to a reverse proxy misconfiguration:

  1. Incorrect rule to catch SPA pages.
    A reverse proxy cannot forward a request to the SPA. 

  2. Incorrect or unreachable SPA host/upstream.
    A reverse proxy or a browser cannot access the SPA by the URL provided in the configuration.

Solution

  1. Check the status of your SPA host and check that it’s reachable from the web browser. The URL configured in the channel's org.hippoecm.hst.configuration.channel.PreviewURLChannelInfo_url property should be accessible from the browser.

Solution prior to brXM 14.2

  1. Check your reverse proxy rule using a Java Regular Expression tester (like this). The rule should be tested against a URL part following after hostname. For example, if the URL of the page inside the Experience manager iframe looks like http://localhost:9080/site/_cmsinternal/channel/news then the test path will be /site/_cmsinternal/channel/news. If you test the following rule:

    <rule>
      <from>^(?:/[^\/]+)?(?:/_cmsinternal)?(?:/spa-ssr)([\?/].*)?$</from>
      <to type="proxy" last="true">http://localhost:3000$0</to>
    </rule>

    Then the regular expression from this rule (^(?:/[^\/]+)?(?:/_cmsinternal)?(?:/spa-ssr)([\?/].*)?$) will not match /site/_cmsinternal/channel/news because the channel is different in the test path.

  2. Check the status of your SPA host and check that it’s reachable from the host with running CMS. The URL from the rule should be accessible from the CMS host: <to type="proxy" last="true">http://localhost:3000$0</to>

The SPA is failing with an error

Problem

The SPA is displaying a 404 error (see Image 4 or Image 5) or 500 error with some stack traces like on Image 6.

404 error

Image 4. 404 error

404 JavaScript error

Image 5. 404 JavaScript error

500 error

Image 6. 500 error

Reason

The potential reason for this behavior is in the incorrectly configured options or cmsBaseUrl. The configuration is pointing to an invalid Delivery API URL.

Solution

  1. Check the options and cmsBaseUrl configuration (brXM 14.2 and above).

  2. Check the presence of the preview query parameter in options.preview.spaBaseUrl.

  3. Make sure that the Delivery API is enabled.

  4. Check that the Delivery API is accessible by the URL requested by the SPA.

  5. Make sure that UrlRewriter is configured correctly:

    <rule>
      <from>^(?:/[^\/]+)?(?:/_cmsinternal)?(?:/spa)([\?/].*)?$</from>
      <to type="proxy" last="true">http://localhost:3000$0</to>
    </rule>
  6. Make sure that the urlrewriter:skippedprefixes property does contain the value _cmssessioncontext.

Overlays disappear after the navigation

Problem

The SPA seems to be fully working, but when you navigate to another page from within the SPA, all the Experience manager controls disappear (see Image 7).

Controls disappeared

Image 7. Controls disappeared

Reason

The SPA navigates to a page from another host. The Experience manager can only work with pages served from the same host.

Solution

  1. Make sure that your navigation links go to the same host as your SPA is hosted at the moment.

  2. Do not include a hostname in the links.

  3. Make sure that you don’t have <base href="..."/> in the page code.

SPA is not loading some static resources

Problem

The SPA cannot load some static resources like JavaScript or CSS (see Image 8) or cannot access some foreign resources like API.

SPA is not loading static resources

Image 8. SPA is not loading static resources

Reason

The potential reason for this behavior is that the SPA is being served by the CMS host. Most probably links to those resources don’t contain a hostname and the browser tries to load them from the current host.

Solution

  1. Use the PUBLIC_URL environment variable to set the prefix for the SPA assets.

    • The server-side rendered demo app provides a possibility to use this option together with Next.js framework.

    • React-scripts has the same option, but it works only for production builds at the moment. When the problem is resolved, it will work for the development mode as well.

  2. You can reuse this variable in paths to your resources or API endpoints. For example, you can set the prefix in your JSX code: <link rel="stylesheet" href={'${process.env.PUBLIC_URL}/static/custom.css'} />.

See more information on how it works in the documentation: https://create-react-app.dev/docs/adding-custom-environment-variables.

SPA has errors related to CORS policy

Problem

The SPA is not working correctly and in the console there are errors with blocked resources due to CORS policy (see Image 9).

CORS-related errors

Image 9. CORS-related errors

Reason

  1. When you run an SPA from outside the CMS it tries to access the Delivery API from a different host. Browsers block such requests due to the Cross-Origin Resource Sharing policy.
  2. The SPA's HTTP client overrides default request headers (such as server-id, endpoint) set by the SDK.

Solution

  1. You can enable your SPA origin to access the Delivery API either by setting the Access-Control-Allow-Origin response header (see Image 10) or, if you need to allow more than one origin, by configuring hosts in the hst:allowedorigins property. It should be done in the host configuration for the channel where you enabled the Delivery API. See Configure the Delivery API (section 'Configure CORS Response Headers') for guidelines on which configuration to use in typical use cases.
  2. Make sure that any additional HTTP headers set by your SPA's HTTP client are appended to the default headers added by the SDK, instead of overriding them.
If you are experiencing intermittent CORS-related errors in a clustered environment, please refer to Channel preview in the Experience manager works intermittently in a clustered environment.

Setting header to enable the SPA origin

Image 10. Setting header to enable the SPA origin

SPA is not loading some CMS resources

Problem

The SPA cannot load some CMS resources like images (see Image 11).

SPA is not loading CMS resources

Image 11. SPA is not loading CMS resources

Reason

The potential reason for this behavior is in the incorrectly configured options.preview.cmsBaseUrl. The configuration is pointing to an unreachable from the browser CMS host.

Solution

  1. Configure options.preview.cmsBaseUrl to contain the correct base URL.

  2. Check that the CMS is accessible by the URL requested by the SPA.

  3. Make sure that you use the getUrl method to generate the URL.

  4. Check that the ad blocker extension is not blocking this resource.

SPA loading is failed with DOMException on History object 

Problem

The SPA cannot put a history state object with an origin different from the CMS host (see Image 12).

SPA is failing with DOMException on History object

Image 12. SPA is failing with DOMException on History object

Reason

The potential reason for this behavior is incorrect <base href="..."/> configuration.

Solution

Make sure that you don’t have <base href="..."/> in the page code.

Some internal links incorrectly recognized as external

  • Inside brXM, some of the internal SPA links are incorrectly handled as external links (see Image 13).

    Image 13. Some of the links recognized as external.
  • Client-side navigation does not work for some links in isomorphic applications.

Reason

There was a bug in brXM causing this behavior.

Solution

Update the CMS to the latest version.

Channel toolbar is not initialized

Inside brXM, from version 14.2 with an updated HST-configuration for the SPA, the channel toolbar is not appearing (see Image 14), but the SPA is fully functioning.

Image 14. Channel toolbar is not initialized.

Reason

  • A deprecated configuration on the SPA side is being used.
  • options and cmsBaseUrl configuration options are exclusive.
  • The SPA is loading components asynchronously but doesn't call the .sync() function after the page has loaded.
  • The Delivery API request in the Experience manager is missing the following headers: Authorization and Referer.

Solution

  • The SPA configuration should not contain the deprecated parameter options.
  • The SPA configuration should be using cmsBaseUrl parameter as of brXM 14.2.
  • If the SPA is loading components asynchronously, call the .sync() function after the page has loaded. See https://www.npmjs.com/package/@bloomreach/spa-sdk#page for details.
  • Check in the SPA configuration if the request option doesn’t have a hard coded path, e.g.: request: { path: '/' }.

Channel preview in the Experience manager works intermittently in a clustered environment

You are running Bloomreach Experience Manager 14.2 or later in a clustered environment and previewing an SPA channel in the Experience manager works intermittently. Sometimes the channel loads properly, sometimes it doesn't. In the latter case, a CORS error about the Access-Control-Allow-Origin header missing might be present in the browser console.

Reason

The most likely cause for this issue is the session affinity between subsequent calls to CMS cluster nodes. The session affinity relies on a server-id query parameter being passed from brXM during the redirect to the SPA. The SPA SDK will retrieve the received parameter and pass it to subsequent requests as a Server-id header. brXM will pick this header and match it to the appropriate session and forward the incoming request to the appropriate cluster node. See Load Balancing Requirements for more information.

If the SPA omits the received server-id parameter, the SPA SDK will not add a Server-id header in the outbound request to the Delivery API and the request will be dispatched in a round-robin fashion. As a result:

  • Calls that hit the cluster node aware of the user's session will succeed with a status 200 and the SPA loading fine in the Experience manager with full editing capabilities.
  • Calls that hit a cluster node that doesn't hold the user's session will fail with a status 401 or 500, the SPA will fail to get a response from the Delivery API, and the toolbar of the Experience manager will not load. A CORS error about the Access-Control-Allow-Origin header missing might be present in the browser's console.

Solution

Always include the full requested path with all its parameters in the property request.path of the configuration object that gets passed to the SDK.

"Mixed content" issues and/or warnings in the Experience manager

Your SPA channel in not displayed in the Experience manager and/or your browser is displaying "mixed content" warnings when viewing an SPA channel in the Experience manager. Your Bloomreach Experience Manager instance uses HTTPS but your SPA uses HTTP.

Reason

Modern browsers typically block the display of a page or display warning messages if secure content (HTTPS) is mixed with insecure content (HTTP).

This can occur in your development environment when, for example, loading an SPA channel in the Experience manager while Bloomreach Experience Manager uses HTTPS and the SPA uses HTTP.

Solution

To avoid mixed content issues while developing your SPA, make sure your SPA uses HTTPS if your Bloomreach Experience Manager instance uses HTTPS.

HTTPS can be enabled in most frontend frameworks through a single configuration variable, see below for some popular frameworks:

Although it is also possible to enable mixed content in most browsers, this workaround is not recommended.

Production instances should always use HTTPS!

Previous versions of an Experience page are not loading in the channel preview when selected in the page's version history in the Experience manager.

Reason

When selecting a specific version from an Experience page's version history in the Experience manager, a version identifier is passed to the frontend application in a request parameter called br_version_uuid. The frontend application must pass the br_version_uuid request parameter on to the Delivery API's Pages endpoint so that the correct version of the page is returned. The SPA SDK implements this out of the box.

If you experience this issue, most likely you are using a custom frontend integration (i.e. not using the SPA SDK) and you are not passing on the br_version_uuid request parameter to the Delivery API. In absence of the version identifier, the Delivery API returns the latest version of the page.

The easiest way to confirm this is the case is by monitoring requests to the frontend application and to the Delivery API while selecting page versions in the Experience manager.

Solution

In your custom frontend integration, always check requests for the presence of the request parameter br_version_uuid and, if present, pass it on in the subsequent request to the Delivery API's Pages endpoint.

 

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?