mirror of
				https://github.com/jaandrle/deka-dom-el
				synced 2025-11-04 15:19:15 +01:00 
			
		
		
		
	🔤 ssr
This commit is contained in:
		
							
								
								
									
										43
									
								
								docs/components/examples/ssr/async-data.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								docs/components/examples/ssr/async-data.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
// Handling async data in SSR
 | 
			
		||||
import { JSDOM } from "jsdom";
 | 
			
		||||
import { S } from "deka-dom-el/signals";
 | 
			
		||||
import { register, queue } from "deka-dom-el/jsdom";
 | 
			
		||||
 | 
			
		||||
async function renderWithAsyncData() {
 | 
			
		||||
	const dom = new JSDOM("<!DOCTYPE html><html><body></body></html>");
 | 
			
		||||
	const { el } = await register(dom);
 | 
			
		||||
 | 
			
		||||
	// Create a component that fetches data
 | 
			
		||||
	function AsyncComponent() {
 | 
			
		||||
			const title= S("-");
 | 
			
		||||
			const description= S("-");
 | 
			
		||||
 | 
			
		||||
		// Use the queue to track the async operation
 | 
			
		||||
		queue(fetch("https://api.example.com/data")
 | 
			
		||||
			.then(response => response.json())
 | 
			
		||||
			.then(data => {
 | 
			
		||||
				title.set(data.title);
 | 
			
		||||
				description.set(data.description);
 | 
			
		||||
			}));
 | 
			
		||||
 | 
			
		||||
		return el("div", { className: "async-content" }).append(
 | 
			
		||||
				el("h2", title),
 | 
			
		||||
				el("p", description)
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Render the page
 | 
			
		||||
	dom.window.document.body.append(
 | 
			
		||||
		el("h1", "Page with Async Data"),
 | 
			
		||||
		el(AsyncComponent)
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	// IMPORTANT: Wait for all queued operations to complete
 | 
			
		||||
	await queue();
 | 
			
		||||
 | 
			
		||||
	// Now the HTML includes all async content
 | 
			
		||||
	const html = dom.serialize();
 | 
			
		||||
	console.log(html);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
renderWithAsyncData();
 | 
			
		||||
							
								
								
									
										47
									
								
								docs/components/examples/ssr/basic-example.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								docs/components/examples/ssr/basic-example.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
// Basic SSR Example
 | 
			
		||||
import { JSDOM } from "jsdom";
 | 
			
		||||
import { register, queue } from "deka-dom-el/jsdom";
 | 
			
		||||
import { writeFileSync } from "node:fs";
 | 
			
		||||
 | 
			
		||||
async function renderPage() {
 | 
			
		||||
	// Create a jsdom instance
 | 
			
		||||
	const dom = new JSDOM("<!DOCTYPE html><html><head><meta charset=\"utf-8\"></head><body></body></html>");
 | 
			
		||||
 | 
			
		||||
	// Register with deka-dom-el and get the el function
 | 
			
		||||
	const { el } = await register(dom);
 | 
			
		||||
 | 
			
		||||
	// Create a simple header component
 | 
			
		||||
	function Header({ title }) {
 | 
			
		||||
		return el("header").append(
 | 
			
		||||
			el("h1", title),
 | 
			
		||||
			el("nav").append(
 | 
			
		||||
				el("ul").append(
 | 
			
		||||
					el("li").append(el("a", { href: "/" }, "Home")),
 | 
			
		||||
					el("li").append(el("a", { href: "/about" }, "About")),
 | 
			
		||||
					el("li").append(el("a", { href: "/contact" }, "Contact"))
 | 
			
		||||
				)
 | 
			
		||||
			)
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Create the page content
 | 
			
		||||
	dom.window.document.body.append(
 | 
			
		||||
		el(Header, { title: "My Static Site" }),
 | 
			
		||||
		el("main").append(
 | 
			
		||||
			el("h2", "Welcome!"),
 | 
			
		||||
			el("p", "This page was rendered with deka-dom-el on the server.")
 | 
			
		||||
		),
 | 
			
		||||
		el("footer", "© 2025 My Company")
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	// Wait for any async operations
 | 
			
		||||
	await queue();
 | 
			
		||||
 | 
			
		||||
	// Get the HTML and write it to a file
 | 
			
		||||
	const html = dom.serialize();
 | 
			
		||||
	writeFileSync("index.html", html);
 | 
			
		||||
 | 
			
		||||
	console.log("Page rendered successfully!");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
renderPage().catch(console.error);
 | 
			
		||||
							
								
								
									
										2
									
								
								docs/components/examples/ssr/intro.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								docs/components/examples/ssr/intro.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
// use NPM or for example https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js
 | 
			
		||||
import { register, unregister, queue } from "deka-dom-el/jsdom";
 | 
			
		||||
							
								
								
									
										35
									
								
								docs/components/examples/ssr/pages.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								docs/components/examples/ssr/pages.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
// ❌ WRONG: Static imports are hoisted and will register before JSDOM is created
 | 
			
		||||
import { register } from "deka-dom-el/jsdom";
 | 
			
		||||
import { el } from "deka-dom-el";
 | 
			
		||||
import { Header } from "./components/Header.js";
 | 
			
		||||
 | 
			
		||||
// ✅ CORRECT: Use dynamic imports to ensure proper initialization order
 | 
			
		||||
import { JSDOM } from "jsdom";
 | 
			
		||||
 | 
			
		||||
async function renderPage() {
 | 
			
		||||
	// 1. Create JSDOM instance first
 | 
			
		||||
	const dom = new JSDOM(`<!DOCTYPE html><html><body></body></html>`);
 | 
			
		||||
 | 
			
		||||
	// 2. Dynamically import jsdom module
 | 
			
		||||
	const { register, queue } = await import("deka-dom-el/jsdom");
 | 
			
		||||
 | 
			
		||||
	// 3. Register and get el function
 | 
			
		||||
	const { el } = await register(dom);
 | 
			
		||||
 | 
			
		||||
	// 4. Dynamically import page components
 | 
			
		||||
	const { Header } = await import("./components/Header.js");
 | 
			
		||||
	const { Content } = await import("./components/Content.js");
 | 
			
		||||
 | 
			
		||||
	// 5. Render components
 | 
			
		||||
	const body = dom.window.document.body;
 | 
			
		||||
	el(body).append(
 | 
			
		||||
		el(Header, { title: "My Page" }),
 | 
			
		||||
		el(Content, { text: "This is server-rendered content" })
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	// 6. Wait for async operations
 | 
			
		||||
	await queue();
 | 
			
		||||
 | 
			
		||||
	// 7. Get HTML and clean up
 | 
			
		||||
	return dom.serialize();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								docs/components/examples/ssr/start.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								docs/components/examples/ssr/start.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
// Basic jsdom integration example
 | 
			
		||||
import { JSDOM } from "jsdom";
 | 
			
		||||
import { register, unregister, queue } from "deka-dom-el/jsdom.js";
 | 
			
		||||
 | 
			
		||||
// Create a jsdom instance
 | 
			
		||||
const dom = new JSDOM("<!DOCTYPE html><html><body></body></html>");
 | 
			
		||||
 | 
			
		||||
// Register the dom with deka-dom-el
 | 
			
		||||
const { el } = await register(dom);
 | 
			
		||||
 | 
			
		||||
// Use deka-dom-el normally
 | 
			
		||||
dom.window.document.body.append(
 | 
			
		||||
  el("div", { className: "container" }).append(
 | 
			
		||||
    el("h1", "Hello, SSR World!"),
 | 
			
		||||
    el("p", "This content was rendered on the server.")
 | 
			
		||||
  )
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
// Wait for any async operations to complete
 | 
			
		||||
await queue();
 | 
			
		||||
 | 
			
		||||
// Get the rendered HTML
 | 
			
		||||
const html = dom.serialize();
 | 
			
		||||
console.log(html);
 | 
			
		||||
 | 
			
		||||
// Clean up when done
 | 
			
		||||
unregister();
 | 
			
		||||
							
								
								
									
										44
									
								
								docs/components/examples/ssr/static-site-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								docs/components/examples/ssr/static-site-generator.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
// Building a simple static site generator
 | 
			
		||||
import { JSDOM } from "jsdom";
 | 
			
		||||
import { register, queue } from "deka-dom-el/jsdom";
 | 
			
		||||
import { writeFileSync, mkdirSync } from "node:fs";
 | 
			
		||||
 | 
			
		||||
async function buildSite() {
 | 
			
		||||
	// Define pages to build
 | 
			
		||||
	const pages = [
 | 
			
		||||
		{ id: "index", title: "Home", component: "./pages/home.js" },
 | 
			
		||||
		{ id: "about", title: "About", component: "./pages/about.js" },
 | 
			
		||||
		{ id: "docs", title: "Documentation", component: "./pages/docs.js" }
 | 
			
		||||
	];
 | 
			
		||||
 | 
			
		||||
	// Create output directory
 | 
			
		||||
	mkdirSync("./dist", { recursive: true });
 | 
			
		||||
 | 
			
		||||
	// Build each page
 | 
			
		||||
	for (const page of pages) {
 | 
			
		||||
		// Create a fresh jsdom instance for each page
 | 
			
		||||
		const dom = new JSDOM("<!DOCTYPE html><html><head><meta charset=\"utf-8\"></head><body></body></html>");
 | 
			
		||||
 | 
			
		||||
		// Register with deka-dom-el
 | 
			
		||||
		const { el } = await register(dom);
 | 
			
		||||
 | 
			
		||||
		// Import the page component
 | 
			
		||||
		const { default: PageComponent } = await import(page.component);
 | 
			
		||||
 | 
			
		||||
		// Render the page with its metadata
 | 
			
		||||
		dom.window.document.body.append(
 | 
			
		||||
			el(PageComponent, { title: page.title, pages })
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		// Wait for any async operations
 | 
			
		||||
		await queue();
 | 
			
		||||
 | 
			
		||||
		// Write the HTML to a file
 | 
			
		||||
		const html = dom.serialize();
 | 
			
		||||
		writeFileSync(`./dist/${page.id}.html`, html);
 | 
			
		||||
 | 
			
		||||
		console.log(`Built page: ${page.id}.html`);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
buildSite().catch(console.error);
 | 
			
		||||
		Reference in New Issue
	
	Block a user