-
-
Notifications
You must be signed in to change notification settings - Fork 213
Server‐Side Rendering
David Ortner edited this page Jan 21, 2025
·
23 revisions
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 async operations such as timers, resource loading and fetch() on the page to complete
// Note that this may get stuck when using intervals or a timer in a loop (see IBrowserSettings for ways to mitigate this)
await window.happyDOM.waitUntilComplete();
// Outputs the rendered result
console.log(window.document.documentElement.outerHTML);
// Cancels all ongoing operations and destroys the Window instance
await window.happyDOM.close();
Happy DOM supports rendering custom elements (web components) server-side using a new web feature called Declarative Shadow DOM.
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", serializable: true });
}
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" shadowrootserializable="">
<style>
:host {
display: inline-block;
background: red;
}
</style>
<div><slot></slot></div>
</template>
</my-custom-element>
*/
console.log(
document.body
.querySelector("div")
.getHTML({ serializableShadowRoots: true })
);
A virtual server makes it possible to simulate an HTTP server that serves files from the local file system.
By using a virtual server, we can, among other things, render the build results of bundlers such as Vite and Webpack.
Read more about virtual server
File structure:
- {root}
- build
- index.html
- style.css
- script.js
import { Browser } from "happy-dom";
const browser = new Browser({
settings: {
fetch: : {
virtualServers: [
{
url: 'https://localhost:8080',
directory: "./build"
}
]
}
}
});
const page = browser.newPage();
await page.goto("https://localhost:8080");
// Waits for async operations such as timers, resource loading and fetch() on the page to complete
// Note that this may get stuck when using intervals or a timer in a loop (see IBrowserSettings for ways to mitigate this)
await page.waitUntilComplete();
// Outputs the rendered result
console.log(
page.mainFrame.document.documentElement.getHTML({ serializableShadowRoots: true })
);
// Closes the browser
await browser.close()
Help Packages