Skip to content

Server-Side Rendering (SSR)

AWC UI supports server-side rendering (SSR) through @awc-ui/core/hydrate. The server emits Declarative Shadow DOM (DSD), including component markup and styles. Client registration makes those elements interactive. Adoption also requires the framework to preserve Stencil’s hydration annotations; the SvelteKit lifecycle below preserves those annotations before component registration.

FrameworkIntegrationExample
React / Next.js@awc-ui/react/server wrappersReact and Next.js SSR
AngularTransform SSR or prerendered HTMLAngular SSR
Vue / NuxtNitro render:html hookVue and Nuxt SSR
Svelte / SvelteKitBuffered server handle and client annotation preservationSvelteKit SSR
Astro / Node.jsTransform complete generated HTMLStandalone starters

For integrations without a dedicated server entry, transform the framework’s complete rendered HTML before returning it. Keep the hydrate import server-side:

import { renderToString } from "@awc-ui/core/hydrate";
const result = await renderToString(renderedHtml, {
fullDocument: true, // false when the framework supplies only its body fragment
serializeShadowRoot: "declarative-shadow-dom",
removeScripts: false,
removeHtmlComments: false,
});
const errors = result.diagnostics.filter((entry) => entry.level === "error");
if (errors.length) throw new Error(errors.map((entry) => entry.messageText).join(" | "));
if (!result.html) throw new Error("AWC SSR returned no HTML");
const hydrated = result.html;

Skip the transform when the response contains no md-* tags. Preserve scripts and comments because the framework and component runtimes use them for hydration. Load @awc-ui/core/css/tokens.css globally. In bundler-based applications, SSR-capable @awc-ui/core/components/* entries register the used elements and allow the bundler to resolve their dependencies. Do not use components-csr/* to hydrate DSD.

@awc-ui/core/ssr/sveltekit contains two helpers with no framework dependencies:

  • createPageTransform(transform) collects HTML chunks until done, then calls the transform once. Create it inside the server handle so concurrent requests have separate buffers. This delays streaming until the document is complete.
  • createSvelteHydration() returns capture() and restore(). Share one instance in an app module. Use SvelteKit 2.70.3 or later. Call capture() from hooks.client.ts’s init, then call restore() in the root layout’s onMount before dynamically importing component entries. Restore only attributes removed by Svelte; application attribute changes take precedence.

The SvelteKit starter and reference app implement the complete sequence. Registration guarded only by browser does not establish this ordering. These helpers ship with the package release matching this source; packed-candidate starter checks validate new APIs before publication.

Component structure and styles arrive in the initial response, avoiding an unstyled first paint while JavaScript loads. Interactions require registration. Canvas charts render their surrounding structure on the server and draw their plots in the browser.

The core SSR smoke test renders every component and fails on render errors or missing expected DSD. The Svelte integration regression checks framework hydration, annotation restoration, shadow-root adoption, and HTML chunk buffering. node scripts/verify-starters.mjs installs packed candidates outside the workspace, builds the starters, and checks server HTML plus browser adoption and interaction. Use --source=registry after release to verify published-package installations; --skip-browser checks only the installation, build, and initial HTML.