Test Your Components

Before you test components, make sure you've reviewed the best practices for portable components.

To check if you can server-side render (SSR) your components, evaluate them with the SSR playground, the SSR test runner, and unit tests with Jest. You can also manually verify that SSR was successful for a component.

The SSR playground lets you render, debug, and experiment with individual components and their children. You can use the playground in client-side rendering (CSR) mode or SSR mode.

To run the playground, navigate to a directory that contains one of these files and run the appropriate playground command.

  • lwc.config.json file
  • package.json file containing an lwc field
  • sfdx-project.json file that points to a project directory containing LWCs

To open the playground in Chrome, run this command in your terminal:

To open the playground in Chrome with DevTools, run this terminal command:

Start at the "leaves" of your component tree, or components that don't contain other components.

  1. Open the component in the SSR playground.
    1. Modify the component properties to test important use cases.
    2. Address errors that are reported during the three phases of hydration—SSR, DOM insertion, and rehydration.
    3. Look for and address any visual bugs in your component.
  2. Enable the CSR toggle to render your component with SSR and CSR side by side.
  3. Use the playground’s comparison tool to ensure the SSR and CSR component instances are visually identical.
  4. Enable the layout shift tool in the Misc section in config to observe any layout shifts during SSR hydration.

The SSR playground's comparison tool.

By default, the SSR playground takes your component through three stages of its SSR lifecycle:

  1. Render the component to HTML markup on the server.
  2. Insert the markup into the DOM on the client.
  3. Hydrate the DOM subtree and associate it with an instance of your component class.

We recommend that you write tests using the SSR test runner to ensure that your components don't regress as you make changes.

Just like you can use Jest to write unit tests for your LWCs, you can use the SSR Test Runner to make assertions about your LWCs in SSR-related scenarios. Create custom SSR tests with out-of-the-box functions, then use the SSR Test Runner to execute them on your project.

This tool works best with Node v18 or v20.

You have to install the SSR Test Runner before you can use it on your project.

To add the test runner to your project, download the @lwc/test-runner package using a package management tool. We recommend using Node Package Manager (npm).

By default, the SSR Test Runner executes SSR tests in headless Chrome. Unlike Jest tests, the SSR tests run in a full-featured web browser.

To create your own SSR tests, you can use these functions from the @lwc/test-runner package.

renderToMarkup() is an asynchronous function that takes:

  • The path to your component
  • The properties that you use for rendering

It returns:

  • Promise<String> where the String is HTML markup

insertMarkupIntoDom() is an asynchronous function that takes:

  • SSR markup, like Promise<String> returned by renderToMarkup()

It returns:

  • Promise<HtmlElement>(), which is a handle to the root element of your SSR-rendered DOM subtree.

hydrateElement() is an async function that takes:

  • A root element, like Promise<HtmlElement> returned from insertMarkupIntoDom()
  • Component properties, which should be the same as those passed into renderToMarkup()

It returns:

  • Promise<Boolean>, where the Boolean indicates whether hydration completed without validation errors. In most cases, you'll want this Boolean value to be true. If hydration failed, review the errors in the console.

You can use this function to chain assertions. To make it easier to test your components, it includes all the assertions from Chai.expect as well as the following additions.

  • throwErrorInConnectedCallback: Asserts any errors thrown in connectedCallback.
  • SSRCorrectly: Checks that all three stages of SSR lifecycle are performed correctly.
  • visuallyIdenticalInCSRandSSR: Performs a pixel match of SSR and CSR components.
  • noLayoutShifts: Ensures that the component didn't have any layout shifts when it was hydrated in DOM.
  • notMakeDomMutationsDuringSSR: Ensures that the component didn't make any DOM mutation.

Here's a sample SSR test that you can execute with the SSR Test Runner.

Ready to invoke the test runner and run your own SSR tests? First, make sure you installed the @lwc/test-runner dependency for your project.

Then, run the test runner using npx or NPM scripts to invoke the test-lwcs command. Tests run in parallel in separate headless Chrome tabs. The tests run fast, and as many as ten thousand tests can complete in under six seconds — depending on your hardware.

Here's the npx command to start the test runner. To customize your test runner output, you can use supported command line flags. By default, the test-lwcs command prints all the browser console output in your terminal.

If you use ZSH, surround SPEC_FILE_PATTERN in single quotes.

To distinguish your project's SSR tests from your Jest tests, use unique file extensions. For example, if your Jest tests follow the format COMPONENT_NAME.spec.js, you can follow the format COMPONENT_NAME.spec-ssr.js for your SSR test files. If you follow this filename format, run your tests like this:

You can also create a shortcut for this command in your project's package.json that uses NPM. Here's an example:

Add these flags to your test-lwcs command to customize its command line output.

FlagDescription
--debugEnables debug mode to find issues with your tests.
--modulesDir <directory name>Invoke the test runner on a specific directory in your project.
--puppeteerExecute the test runner in the Puppeteer browser environment.
--quietPrevents browser console output from printing in your terminal.

If the test runner returns failures for hydrateElement, noLayoutShifts, or notMakeDomMutationsDuringSSR, you likely have performance issues on the client-side.

When a component is rendered on a page, you can verify that SSR was successful by looking at the DOM elements. To determine if an island or component tree implemented SSR successfully:

  1. In Chrome, right-click the page and select to View Page Source. If you use Firefox or another browser, the View Page Source tool might be named something else, like Inspect or View Selection Source.
  2. Search for some HTML or text from the component. If you find it, then SSR was successful.

In Experience Cloud apps only, search for webruntime-island-container, which wraps each CSR’ed and hydrated island. Review the output for the following scenarios. For more information about Experience Cloud hydration capabilities, see Hydration Capabilities for Islands (Experience Cloud).

CSR-only — The wrapper has no inner HTML.

SSR with hydration — The wrapper has inner HTML and a data-lwr-props-id attribute.

SSR-only (not hydrated) — There's no wrapper, so the HTML exists in the page source.

Now that you've...

  • Configured your components for SSR
  • Aligned them with the SSR best practices
  • Evaluated them in SSR testing environments

...you can enable SSR for a page of your LWR site by following the instructions in Enable SSR for LWR Apps. If you have an Experience Cloud site, review Hydration Capabilities for Islands (Experience Cloud) instead.

Enabling SSR for an entire page is a prerequisite for configuring a single component island for SSR.