@lentystyle/ssr is the SSR orchestration layer that injects CSS and runtime payload into a route HTML snapshot. It does not render framework HTML itself; it consumes an existing HTML snapshot and the .luis source list for that route.
Compiler -> Hybrid -> SSR -> HTML ResponseMinimal Setup
Section titled “Minimal Setup”pnpm add @lentystyle/ssrnpm install @lentystyle/ssryarn add @lentystyle/ssrWhat SSR Does
Section titled “What SSR Does”- Takes a route HTML snapshot
- Compiles the
.luissource list for that route - Injects the generated CSS into the HTML
- Writes the route payload as
<script type="application/json"> - Provides adapter seams for framework or server integration
- Offers optional in-memory cache for repeated renders in the same process
- Validates request HTML and source envelope inputs in strict mode with
@lentystyle/core/guard/ssr
What SSR Does Not Do
Section titled “What SSR Does Not Do”- Does not render framework HTML for you
- Does not start the browser runtime
- Does not auto-discover route sources
- Does not provide distributed cache or persistent storage
Guard Profile
Section titled “Guard Profile”The SSR request flow uses @lentystyle/core/guard/ssr.
This adapter:
- uses the
strictpreset by default - enforces
htmlMode: 'ssr' - keeps the LentyStyle SSR payload and bootstrap allowlist strictly SSR-only
- blocks invalid request HTML or source envelope inputs before hybrid compilation starts
Default guard flow
Section titled “Default guard flow”In high-level SSR helpers you do not enable guard separately; it runs inside the request render flow.
import { renderLentySsrSnapshot } from '@lentystyle/ssr'
await renderLentySsrSnapshot({}, { routeId: '/docs/', html: '<html><head></head><body><div class="card"></div></body></html>', sources: [ { sourceId: 'docs.luis', source: '.card { color: #0f172a; }', }, ],})The built-in behavior is fixed:
preset: 'strict'htmlMode: 'ssr'
When custom guard behavior is needed
Section titled “When custom guard behavior is needed”The public renderLentySsrSnapshot() and createLentySsrIntegration() surfaces do not directly accept guardPolicy. If custom validation is needed, you must run guard separately one layer above SSR or drop to lower-level orchestration.
import { scanSnapshotEnvelope } from '@lentystyle/core/guard/ssr'
const findings = scanSnapshotEnvelope( { routeId: '/docs/', html: '<html><head></head><body><div class="card"></div></body></html>', sources: [ { sourceId: 'docs.luis', source: '.card { color: #0f172a; }', }, ], }, { preset: 'strict', htmlMode: 'ssr' },)
console.log(findings.length) // 0Recommended Starting Point
Section titled “Recommended Starting Point”- Generate the route HTML snapshot
- Prepare the
.luissource list - Choose the right SSR surface
- Write the
result.htmloutput to the response
Available surfaces:
renderLentySsrSnapshot()→ one-time rendercreateLentySsrIntegration()→ reusable direct surfacecreateLentySsrFrameworkAdapter()→ framework seamcreateLentySsrProd()→ helper with process-local cache support
Quick Example
Section titled “Quick Example”import { renderLentySsrSnapshot } from '@lentystyle/ssr'
const result = await renderLentySsrSnapshot( { mode: 'ssr' }, { routeId: '/docs/', html: '<html><head></head><body><div class="card"></div></body></html>', sources: [ { sourceId: 'site.luis', source: '.card { color: red; }', }, ], },)After the call:
result.csscontains the generated CSSresult.runtimePayloadcontains the hybrid route payloadresult.htmlcontains the final injected HTML
When luis.config.mjs Matters
Section titled “When luis.config.mjs Matters”Low-level SSR APIs are object-based and do not require luis.config.mjs. But in app-level preview and project helper flows it is more useful to keep common SSR settings in the same config file.
import { defineLuisConfig } from '@lentystyle/core'
export default defineLuisConfig({ ssr: { mode: 'ssr', outDirName: 'dist-ssr', defaultRuntimeOptions: '', include: ['**/*.html'], },})Runtime and Guard Separation Inside SSR
Section titled “Runtime and Guard Separation Inside SSR”SSR also keeps convenience and hardening roles separate:
- the browser runtime stays optional and convenience-oriented on the client side
@lentystyle/core/guard/ssrhardens the incoming HTML snapshot and source envelope input on the server side
Thanks to this separation, SSR can stay strict about payload and bootstrap HTML while the browser runtime keeps its own standalone policy model.
Next Steps
Section titled “Next Steps”Configfor request-level and project-level settingsBrowser Runtimefor browser-side convenience behavior@lentystyle/guarddocs for the fail-closed validation model