Skip to content

Server‐Side Rendering

David Ortner edited this page Apr 19, 2024 · 4 revisions

Simple Example

import { Window } from 'happy-dom';

const window = new Window({
	innerWidth: 1024,
	innerHeight: 768,
	url: 'http://localhost:8080'
});
const document = window.document;

document.write(`
    <html>
        <head>
             <title>Test page</title>
        </head>
        <body>
            <div class="root"></div>
            <script src="app.js"></script>
        </body>
    </html>
`);

// Waits for all async operations to complete
// Note that this may get stuck when using intervals or a timer in a loop
await window.happyDOM.waitUntilComplete();

// Do something with the result
console.log(window.document.documentElement.outerHTML);

// Cancels all ongoing operations and destroys the Window instance
await window.happyDOM.close();

Web Compontents

Happy DOM supports rendering custom elements (web components) server-side using a new web feature called Declarative Shadow DOM.

Unsupported browsers will safely fallback to being rendered using client side Javascript.

import { Window } from 'happy-dom';

const window = new Window({
	innerWidth: 1024,
	innerHeight: 768,
	url: 'http://localhost:8080'
});
const document = window.document;

document.write(`
    <html>
        <head>
             <title>Test page</title>
        </head>
        <body>
            <div>
                <my-custom-element>
                    <span>Slotted content</span>
                </my-custom-element>
            </div>
            <script>
                class MyCustomElement extends HTMLElement {
                    constructor() {
                        super();
                        this.attachShadow({ mode: 'open' });
                    }

                    connectedCallback() {
                        this.shadowRoot.innerHTML = \`
                            <style>
                                :host {
                                    display: inline-block;
                                    background: red;
                                }
                            </style>
                            <div><slot></slot></div>
                        \`;
                    }
                }

                customElements.define('my-custom-element', MyCustomElement);
            </script>
        </body>
    </html>
`);

/*
Will output:
<my-custom-element>
    <span>Slotted content</span>
    <template shadowroot="open">
        <style>
            :host {
                display: inline-block;
                background: red;
            }
        </style>
        <div><slot></slot></div>
    </template>
</my-custom-element>
*/
console.log(document.body.querySelector('div').getInnerHTML({ includeShadowRoots: true }));
Clone this wiki locally