Comprehensive server-side rendering with streaming support and optimization features. Qwik's SSR is built around resumable architecture, allowing applications to start on the server and seamlessly continue on the client.
Render Qwik applications to HTML strings for traditional SSR.
/**
* Render Qwik application to HTML string
* @param opts - Render configuration options
* @returns Promise resolving to render result
*/
function renderToString(opts: RenderToStringOptions): Promise<RenderToStringResult>;
// Render to string configuration
interface RenderToStringOptions {
/** Root JSX node to render */
node: JSXNode;
/** Optional manifest for optimization */
manifest?: QwikManifest | ResolvedManifest;
/** Locale for internationalization */
locale?: string;
/** Base URL for the application */
base?: string;
/** Container HTML tag name */
containerTagName?: string;
/** Container attributes */
containerAttributes?: Record<string, string>;
/** Document serialization options */
serialize?: SerializeDocumentOptions;
/** Prefetch strategy */
prefetchStrategy?: PrefetchStrategy;
/** Server data */
serverData?: Record<string, any>;
}
// Render to string result
interface RenderToStringResult {
/** Generated HTML string */
html: string;
/** Prefetch resources */
prefetchResources: PrefetchResource[];
/** Timing information */
timing: RenderTiming;
/** Symbol to prefetch mappings */
symbolsToPrefetch: SymbolsToPrefetch;
}Usage Examples:
import { renderToString } from "@builder.io/qwik/server";
import { App } from "./app";
// Basic string rendering
const result = await renderToString({
node: <App />,
manifest: manifest,
});
console.log(result.html); // HTML string
console.log(result.timing); // Performance metrics
// Advanced string rendering with options
const advancedResult = await renderToString({
node: <App />,
manifest: manifest,
locale: "en-US",
base: "/my-app/",
containerTagName: "main",
containerAttributes: {
"data-app": "true",
"class": "app-container",
},
prefetchStrategy: {
implementation: "link-prefetch",
},
serverData: {
user: { id: 1, name: "John" },
theme: "dark",
},
});Render applications as streams for improved perceived performance.
/**
* Render Qwik application to stream
* @param opts - Stream render configuration
* @returns Promise resolving to stream result
*/
function renderToStream(opts: RenderToStreamOptions): Promise<RenderToStreamResult>;
// Stream render configuration
interface RenderToStreamOptions {
/** Root JSX node to render */
node: JSXNode;
/** Optional manifest for optimization */
manifest?: QwikManifest | ResolvedManifest;
/** Locale for internationalization */
locale?: string;
/** Base URL for the application */
base?: string;
/** Container HTML tag name */
containerTagName?: string;
/** Container attributes */
containerAttributes?: Record<string, string>;
/** Streaming configuration */
stream?: StreamingOptions;
/** Prefetch strategy */
prefetchStrategy?: PrefetchStrategy;
/** Server data */
serverData?: Record<string, any>;
}
// Stream render result
interface RenderToStreamResult {
/** Readable stream of HTML chunks */
html: ReadableStream<Uint8Array>;
/** Prefetch resources */
prefetchResources: PrefetchResource[];
/** Timing information */
timing: RenderTiming;
/** Symbol to prefetch mappings */
symbolsToPrefetch: SymbolsToPrefetch;
}
// Streaming configuration options
interface StreamingOptions {
/** Buffer size for streaming chunks */
bufferSize?: number;
/** Initial data to stream */
initialChunk?: string;
/** Final data to stream */
finalChunk?: string;
}Usage Examples:
import { renderToStream } from "@builder.io/qwik/server";
import { App } from "./app";
// Basic stream rendering
const result = await renderToStream({
node: <App />,
manifest: manifest,
});
// Convert stream to response (Node.js/Web API)
const response = new Response(result.html, {
headers: {
"Content-Type": "text/html; charset=utf-8",
},
});
// Advanced streaming with custom options
const streamResult = await renderToStream({
node: <App />,
manifest: manifest,
stream: {
bufferSize: 1024,
initialChunk: "<!DOCTYPE html><html><head>",
finalChunk: "</body></html>",
},
});Initialize server platform with manifest and configuration.
/**
* Set up server platform with manifest
* @param manifest - Optional Qwik manifest or resolved manifest
* @returns Promise that resolves when platform is ready
*/
function setServerPlatform(manifest?: Partial<QwikManifest | ResolvedManifest>): Promise<void>;Usage Examples:
import { setServerPlatform } from "@builder.io/qwik/server";
import manifest from "./dist/q-manifest.json";
// Initialize server platform
await setServerPlatform(manifest);
// Now ready to render applicationsResolve and process Qwik manifests for optimization.
/**
* Resolve Qwik manifest for optimization
* @param manifest - Partial or full manifest
* @returns Resolved manifest with all optimizations
*/
function resolveManifest(manifest?: Partial<QwikManifest | ResolvedManifest>): ResolvedManifest;
// Qwik manifest interface
interface QwikManifest {
/** Bundle definitions */
bundles: QwikBundle[];
/** Symbol mappings */
symbols: Record<string, QwikSymbol>;
/** Entry points */
entryStrategy: EntryStrategy;
/** Platform information */
platform: Record<string, any>;
}
// Resolved manifest with optimizations
interface ResolvedManifest extends QwikManifest {
/** Resolved bundle graph */
bundleGraph: QwikBundleGraph;
/** Optimized symbol mappings */
symbolMap: Record<string, string>;
}Generate loader and prefetch scripts for client-side optimization.
/**
* Generate Qwik loader script
* @param opts - Loader script options
* @returns JavaScript code string
*/
function getQwikLoaderScript(opts?: QwikLoaderOptions): string;
/**
* Generate prefetch worker script
* @param opts - Prefetch worker options
* @returns JavaScript code string
*/
function getQwikPrefetchWorkerScript(opts?: PreloaderOptions): string;
// Qwik loader options
interface QwikLoaderOptions {
/** Events to capture during loading */
events?: string[];
/** Debug mode */
debug?: boolean;
/** Custom loader path */
include?: "always" | "never" | "auto";
}
// Preloader options
interface PreloaderOptions {
/** Base URL for resources */
base?: string;
/** Prefetch strategy */
strategy?: PrefetchStrategy;
}Usage Examples:
import {
getQwikLoaderScript,
getQwikPrefetchWorkerScript
} from "@builder.io/qwik/server";
// Generate loader script
const loaderScript = getQwikLoaderScript({
events: ["click", "input", "scroll"],
debug: process.env.NODE_ENV === "development",
});
// Generate prefetch worker script
const prefetchScript = getQwikPrefetchWorkerScript({
base: "/build/",
strategy: { implementation: "service-worker" },
});
// Include in HTML
const html = `
<!DOCTYPE html>
<html>
<head>
<script>${loaderScript}</script>
<script>${prefetchScript}</script>
</head>
<body>
${appHtml}
</body>
</html>
`;Utility functions for server-side operations.
/**
* Get version information for all Qwik packages
* @returns Object with package versions
*/
function versions(): { [key: string]: string };Usage Examples:
import { versions } from "@builder.io/qwik/server";
const packageVersions = versions();
console.log(packageVersions);
// {
// "@builder.io/qwik": "1.16.0",
// "@builder.io/qwik-city": "1.16.0"
// }Type definitions for rendering configuration.
// Generic render function type
type Render = (opts: RenderOptions) => Promise<RenderResult>;
// Stream render function type
type RenderToStream = (opts: RenderToStreamOptions) => Promise<RenderToStreamResult>;
// String render function type
type RenderToString = (opts: RenderToStringOptions) => Promise<RenderToStringResult>;
// Base render options
interface RenderOptions {
node: JSXNode;
manifest?: QwikManifest | ResolvedManifest;
}
// Base render result
interface RenderResult {
prefetchResources: PrefetchResource[];
timing: RenderTiming;
}
// Render timing information
interface RenderTiming {
createTime: number;
renderTime: number;
snapshotTime: number;
}
// Document serialization options
interface SerializeDocumentOptions {
/** Include Qwik loader script */
includeQwikLoader?: boolean;
/** Include prefetch resources */
includePrefetch?: boolean;
/** Custom document serialization */
serialize?: boolean;
}
// Prefetch resource definition
interface PrefetchResource {
/** Resource URL */
url: string;
/** Resource type */
type: "script" | "style" | "font" | "image";
/** Loading strategy */
as?: string;
}
// Prefetch implementation strategies
interface PrefetchImplementation {
/** Implementation type */
type: "link-prefetch" | "link-preload" | "service-worker" | "web-worker";
/** Implementation-specific options */
options?: Record<string, any>;
}
// Prefetch strategy configuration
interface PrefetchStrategy {
/** Implementation to use */
implementation: PrefetchImplementation | string;
/** Symbol filtering */
symbolsToPrefetch?: "all" | "events" | "visible" | "auto";
}
// Streaming order control
type InOrderAuto = { type: "auto" };
type InOrderDisabled = { type: "disabled" };
type InOrderStreaming = { type: "streaming"; strategy: string };
// Symbols to prefetch mapping
type SymbolsToPrefetch = Record<string, string[]>;Complete Example: Express.js Integration
import express from "express";
import {
renderToStream,
setServerPlatform,
getQwikLoaderScript
} from "@builder.io/qwik/server";
import { App } from "./app";
import manifest from "./dist/q-manifest.json";
const app = express();
// Initialize Qwik server platform
await setServerPlatform(manifest);
app.get("*", async (req, res) => {
try {
const result = await renderToStream({
node: <App url={req.url} />,
manifest,
locale: req.headers["accept-language"]?.split(",")[0] || "en",
base: "/build/",
containerTagName: "div",
containerAttributes: {
id: "app",
"data-server-rendered": "true",
},
serverData: {
url: req.url,
userAgent: req.headers["user-agent"],
},
});
res.setHeader("Content-Type", "text/html; charset=utf-8");
// Stream the response
const reader = result.html.getReader();
const pump = async () => {
const { done, value } = await reader.read();
if (done) {
res.end();
return;
}
res.write(value);
pump();
};
pump();
} catch (error) {
res.status(500).send("Server Error");
}
});