HomeGuides
Submit Documentation FeedbackJoin Developer CommunityLog In

Server-side rendering SSR guidelines for Spire

This topic describes server-side rendering SSR guidelines for Spire.

For Spire Alpha, only pages accessed by SEO crawlers are required to render server-side. These are:

  • Product Detail Pages
  • Brand & Brand Detail Pages
  • Content Pages
  • Product/Category List pages

Other pages with fast APIs and hidden behind logins are nice to have, including:

  • My Account and its children
  • Cart and Checkout
  • Lists

Authenticated content that depends on slow API calls should not use server-side rendering, or the page will appear blank to the user until all APIs respond.

React functionality

As of React 16.13.1, most React functionality works for server-side rendering, except for useEffectuseLayoutEffect. The components will otherwise work, but the hooks will not run until client-side hydration. If the logic behind those hooks is required for SEO, you must instead implement the component as a class component and move API-calling
logic into UNSAFE_componentWillMount. You can split a component into separate class and functional components if you wish to use the functional approaches for part of it.

Spire supports SSR in react components that use UNSAFE_componentWillMount to load data. It has a render loop that will rerender the site while persisting the redux store between renders. It will continue the loop until there are no new promises created during a render, or until it has rendered 10 times. If it renders 10 times then it will either log a warning or throw an exception.

The content of the warning or exception will look something like this:

During SSR of /MyCustomPage there was a new promise added on loop 10.
This usually indicates a problem with react state management that will affect performance.
The new promise was added at the following location:

For versions prior to 5.1.2203 it will always log a warning.

As of 5.1.2203 it will log a warning in production (production meaning a production build of spire, not a site in production), as long as the environment variable FAIL_ON_PROMISE_LOOPS is not true.
When not in production, it will throw an exception unless the environment variable BYPASS_FAIL_ON_PROMISE_LOOPS is true

An example of code that will cause a promise loop

UNSAFE_componentWillMount(): void {
    // this dispatches a redux action that loads data from an API
    loadCategories();
}

Fixing the promise loop requires checking if data is currently loading, or was already loaded.

UNSAFE_componentWillMount(): void {
    const { categoriesDataView, loadCategories } = this.props;
    if (!categoriesDataView.isLoading && !categoriesDataView.value) {
        // this will now only dispatch an action on the first render in the loop
        loadCategories();
    }
}

Verify SSR functionality by refreshing the page. The initial HTML returned by the server should have the desired content, and the client-side JavaScript should not alter that content. Test links and other functionality with JavaScript disabled to ensure that SEO crawlers can navigate.

📘

Note

It is expected that React 17 will offer an alternative to UNSAFE_componentWillMount that enables functional components to be used in all scenarios.


Did this page help you?