Server-side rendering SSR guidelines for Spire
Describes server-side rendering SSR guidelines for Spire.
Only pages accessed by SEO crawlers are required to render server-side for Spire. 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.
Updated over 1 year ago