Litro renders all pages on the server before sending HTML to the browser. The SSR strategy depends on which adapter your project uses:
@lit-labs/ssr or @microsoft/fast-ssr. DSD is a browser-native way to express shadow roots in HTML — no JavaScript required to parse the initial structure.render(), and stringifies the result.The SSR output streams directly to the browser as it's generated. This means the browser can start parsing and rendering the top of the page before the server finishes rendering the bottom.
Add @lit-labs/ssr-client/lit-element-hydrate-support.js as the first import in your app.ts. This patches LitElement to support DSD hydration:
// app.ts
import '@lit-labs/ssr-client/lit-element-hydrate-support.js'; // MUST be first
import '@beatzball/litro/runtime/LitroOutlet.js';
// ...
Components that access window, document, or localStorage at module evaluation time will throw during SSR. Guard such access:
// Safe — only runs in the browser
override firstUpdated() {
if (typeof localStorage !== 'undefined') {
this._theme = localStorage.getItem('theme') ?? 'light';
}
}
For components that can't be made SSR-safe, use <litro-client-only> to skip SSR entirely.