Best practices for SSR compatible JSS apps

Version: 20.x

To stay compatible with the authoring environment so that content authors can edit components in a graphical user interface, we recommend you build all JSS components compatible with server-side rendering (SSR), even if the production build uses client-side rendering.

We strongly recommend you follow the SSR guides and best practices for your framework of choice, as well as any recommendations for SSR compatibility of third-party libraries you use in your JSS apps.

Treat browser-specific objects with care

To preserve SSR compatibility, limit as much as possible the usage of browser-specific objects, such as:

  • window

  • document

  • localStorage

  • sessionStorage

If using these browser-specific objects is necessary, wrap the code in a conditional that checks the current execution context or place the code in a lifecycle method that does not fire during SSR.

Use the isServer() helper method provided by JSS

JSS has the utility function isServer() for checking whether the app is currently rendering in a Node.js context. You can use it with control flows to handle SSR context. For example:

RequestResponse
import { isServer } from ‘@sitecore-jss/sitecore-jss’;

fetch('https://some-url', { options }).catch((error) => {
  if (isServer()) {
    // use Node's global console object to log the error
    console.error('Error:', error);
  } else {
    // Notify the user about the error. Note: this is for code demonstration only;
    // this is not at attractive way to show errors to end-users
    window.alert('An error has occurred');
  }
});

Verify third-party dependencies

When using third-party dependencies in your project, you might want additional configuration or middleware to support SSR.

Check the documentation for SSR compatibility - look for anything special regarding initialization options, render-time params, build configuration specific to SSR, and so on.

Common dependencies to be mindful of are:

  • Data fetching libraries such as Axios and SWR.

  • State management libraries. For example, Redux or Vuex.

  • GraphQL data graph implementations such as Apollo.

  • Routing libraries (react-router, vue-router).

  • CSS-in-JS libs, such as styled-components or emotion.

  • Document head manager libraries such as react-helmet.

  • Dynamically loaded components. For example, react-loadable.

Do you have some feedback for us?

If you have suggestions for improving this article,