Web component SSR using puppeteer

Viewed 545

I am trying to use puppeteer to render a simple web component using this code:

async function ssr(url) {
  const start = Date.now();
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.setJavaScriptEnabled(true);
  await page.goto(url, { waitUntil: 'networkidle0' });
  await page.waitForSelector('#hello');

  const html = await page.content();

  await browser.close();

  const ttRenderMs = Date.now() - start;
  console.info(`Headless rendered page in: ${ttRenderMs}ms`);

  return { html, ttRenderMs };
}

This is what it tries to load:

<!DOCTYPE html>
<html>

<head>
  <title>Lit + SSR</title>
</head>

<body>
  <script type="module">
    import { LitElement, html } from 'lit-element';

    export class HelloElement extends LitElement {
      static get properties() {
        return {
          name: { type: String }
        };
      }

      render() {
        return html`
          Hello, <b>${this.name}</b>!
        `;
      }
    }

    customElements.define('x-hello', HelloElement);
  </script>

  <x-hello id="hello" name="Ninja"></x-hello>
</body>

</html>

While puppeteer is able to render the page correctly (verified by page.screenshot), page.content or page.evaluate(() => document.documentElement.innerHTML) both do not return the shadow DOM and therefore is useless.

How do I get puppeteer to return me the markup that includes the shadow root?

0 Answers
Related