Configure Components for Server-Side Rendering (SSR)

To successfully render a component on the server side, it has to meet all of the following criteria:

  1. The functions that execute during SSR must be portable
  2. The functions that execute during SSR must be synchronous.
  3. The component uses light DOM (recommended) or native shadow DOM.

Follow these steps (in order) to make components SSRable.

A component is portable if it can run without browser APIs. Your components can’t have any dependencies on browser APIs because the server isn’t a browser.

During SSR, the Lightning Web Components (LWC) framework executes only these functions for each of your components and all of their imported dependencies:

  • constructor
  • connectedCallback()
  • getters
  • setters
  • any other functions called by these functions

Components with non-portable code will break your site. If a component uses browser APIs, you have to modify it to ensure it doesn't assume that those APIs are always available.

For example, you should remove these non-portable code and objects from components that you want to SSR.

  • window
  • document
  • selector functions (such as querySelector and querySelectorAll)
  • JavaScript eventing

The LWC ESLint Plugin helps you determine if your components follow best practices for APIs or methods usage. The plugin's SSR preset, @salesforce/eslint-config-lwc/ssr, lets you identify non-portable components.

You can configure the plugin with rules from this list. For example, here are a few rules you should enable to identify non-portable components.

  • Disallow access to global browser APIs during SSR (lwc/no-restricted-browser-globals-during-ssr)
  • Disallow access to unsupported properties on this during SSR (lwc/no-unsupported-ssr-properties)
  • Disallow usage of process.env.NODE_ENV in SSR (lwc/no-node-env-in-ssr)

Additionally, the plugin can help you identify non-portable utilities and libraries. If a library isn't portable, your page won't load correctly during SSR.

Since the SSR process for Lightning web components (LWCs) runs in one synchronous pass, you should only have synchronous code in server-rendered pages and components.

Server-side asynchronous code executes but doesn't complete during SSR. The resulting page won't break, but it can render unexpected content that's difficult to debug.

Asynchronous code includes:

However, server-rendered pages and components can include asynchronous code that doesn't execute on the server. For example, you can include asynchronous code in renderedCallBack() or event handlers, but you can't add it to connectedCallback() or getters. To test if asynchronous code is unsafe, use the ESLint plugin.

By default, server-rendered components are rendered in native shadow DOM. However, we recommend using light DOM instead.

Light DOM eases third-party integrations (like Google Analytics) and global styling. Enabling light DOM ensures that LWC renders regular HTML markup instead of creating a native web component. The markup is also referred to as light DOM since it isn’t contained within a shadow root.

To enable light DOM on your Lightning web component, use the renderMode static property.

In your template, use the lwc:render-mode directive.

Shadow DOM encapsulates a component's internals and styling. Server-rendered components can use native shadow DOM instead of light DOM.

Synthetic shadow DOM is not supported due to limitations on browser API usage.

After you've configured a component for SSR, make sure it follows the Best Practices for Portable Components.

See Also