SPA Integration Troubleshooting - Bloomreach Experience - Open Source CMS
16-11-2020

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.

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.

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 Page Model 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 Page Model API is enabled.

  4. Check that the Page Model 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

When you run an SPA from outside the CMS it tries to access the Page Model API from a different host. Browsers block such requests due to the Cross-Origin Resource Sharing policy.

Solution

You can enable your SPA origin to access the Page Model 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 Page Model API. See Configure Page Model API (section 'Configure CORS Response Headers') for guidelines on which configuration to use in typical use cases.

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.

Solution

  • The SPA configuration should not contain the deprecated parameter options.
  • The SPA configuration should be using cmsBaseUrl parameter as of brXM 14.2.

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 Page Model 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 Page Model 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!
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?