@llui/vike 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @llui/vike
2
2
 
3
- [Vike](https://vike.dev) SSR adapter for [LLui](https://github.com/fponticelli/llui). Server-side rendering with client hydration.
3
+ [Vike](https://vike.dev) SSR/SSG adapter for [LLui](https://github.com/fponticelli/llui). Server-side rendering with client hydration, or static site generation via prerendering.
4
4
 
5
5
  ```bash
6
6
  pnpm add @llui/vike
@@ -8,49 +8,72 @@ pnpm add @llui/vike
8
8
 
9
9
  ## Setup
10
10
 
11
- Export the hooks from your Vike render files:
11
+ Use sub-path imports to keep jsdom out of the client bundle:
12
12
 
13
13
  ```ts
14
14
  // pages/+onRenderHtml.ts
15
- export { onRenderHtml } from '@llui/vike'
15
+ export { onRenderHtml } from '@llui/vike/server'
16
16
  ```
17
17
 
18
18
  ```ts
19
19
  // pages/+onRenderClient.ts
20
- export { onRenderClient } from '@llui/vike'
20
+ export { onRenderClient } from '@llui/vike/client'
21
21
  ```
22
22
 
23
- ## How It Works
24
-
25
- ### Server (`onRenderHtml`)
23
+ ### Custom Document Template
26
24
 
27
- Renders the component tree to an HTML string on the server. Runs `resolveEffects()` to prefetch async data before serializing the initial state into the page.
25
+ Use `createOnRenderHtml` to control the full HTML document add stylesheets, meta tags, favicons:
28
26
 
29
27
  ```ts
30
- // What happens internally:
31
- // 1. resolveEffects(componentDef) -- resolve SSR data
32
- // 2. renderToString(componentDef, resolvedState) -- generate HTML
33
- // 3. Serialize state into <script> tag for hydration
28
+ // pages/+onRenderHtml.ts
29
+ import { createOnRenderHtml } from '@llui/vike/server'
30
+
31
+ export const onRenderHtml = createOnRenderHtml({
32
+ document: ({ html, state, pageContext }) => `<!DOCTYPE html>
33
+ <html lang="en">
34
+ <head>
35
+ <meta charset="utf-8" />
36
+ <link rel="stylesheet" href="/styles.css" />
37
+ </head>
38
+ <body>
39
+ <div id="app">${html}</div>
40
+ <script>window.__LLUI_STATE__ = ${state}</script>
41
+ </body>
42
+ </html>`,
43
+ })
34
44
  ```
35
45
 
36
- ### Client (`onRenderClient`)
46
+ ### Custom Container
37
47
 
38
- Hydrates the server-rendered HTML on the client. Attaches event listeners and reactive bindings to existing DOM nodes without re-rendering.
48
+ Use `createOnRenderClient` to configure the mount container or add lifecycle hooks:
39
49
 
40
50
  ```ts
41
- // What happens internally:
42
- // 1. Read serialized state from the page
43
- // 2. hydrateApp(componentDef, existingDOM, state)
44
- // 3. Component is now interactive
51
+ // pages/+onRenderClient.ts
52
+ import { createOnRenderClient } from '@llui/vike/client'
53
+
54
+ export const onRenderClient = createOnRenderClient({
55
+ container: '#root',
56
+ onMount: () => console.log('Page ready'),
57
+ })
45
58
  ```
46
59
 
47
- ## API
60
+ ## How It Works
61
+
62
+ ### Server (`onRenderHtml`)
63
+
64
+ Renders the component to HTML via `renderToString()`. Automatically initializes jsdom for server-side DOM (lazy-loaded to avoid client bundle pollution). Serializes state into a `<script>` tag for hydration.
48
65
 
49
- | Export | Description |
50
- | ---------------- | ---------------------------------------------------- |
51
- | `onRenderHtml` | Vike server hook -- renders component to HTML string |
52
- | `onRenderClient` | Vike client hook -- hydrates server-rendered DOM |
66
+ ### Client (`onRenderClient`)
67
+
68
+ Hydrates the server-rendered HTML on the client. Attaches event listeners and reactive bindings to existing DOM nodes without re-rendering. Falls back to fresh `mountApp()` for client-side navigations.
69
+
70
+ ## API
53
71
 
54
- ## License
72
+ | Export | Sub-path | Description |
73
+ | ---------------------- | ------------------- | ------------------------------------------- |
74
+ | `onRenderHtml` | `@llui/vike/server` | Default server hook — minimal HTML template |
75
+ | `createOnRenderHtml` | `@llui/vike/server` | Factory for custom document templates |
76
+ | `onRenderClient` | `@llui/vike/client` | Default client hook — hydrate or mount |
77
+ | `createOnRenderClient` | `@llui/vike/client` | Factory for custom container/lifecycle |
55
78
 
56
- MIT
79
+ The barrel export (`@llui/vike`) re-exports everything, but prefer sub-path imports to avoid bundling jsdom into the client.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
- export { onRenderHtml } from './on-render-html';
2
- export { onRenderClient } from './on-render-client';
1
+ export { onRenderHtml, createOnRenderHtml } from './on-render-html';
2
+ export type { PageContext, DocumentContext, RenderHtmlResult } from './on-render-html';
3
+ export { onRenderClient, createOnRenderClient } from './on-render-client';
4
+ export type { ClientPageContext, RenderClientOptions } from './on-render-client';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACnE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAEtF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzE,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA"}
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { onRenderHtml } from './on-render-html';
2
- export { onRenderClient } from './on-render-client';
1
+ export { onRenderHtml, createOnRenderHtml } from './on-render-html';
2
+ export { onRenderClient, createOnRenderClient } from './on-render-client';
3
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAGnE,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA"}
@@ -9,5 +9,29 @@ export interface ClientPageContext {
9
9
  data?: unknown;
10
10
  isHydration?: boolean;
11
11
  }
12
+ export interface RenderClientOptions {
13
+ /** CSS selector for the mount container. Default: '#app' */
14
+ container?: string;
15
+ /** Called after mount or hydration completes */
16
+ onMount?: () => void;
17
+ }
18
+ /**
19
+ * Default onRenderClient hook.
20
+ * Hydrates if isHydration is true, otherwise mounts fresh.
21
+ */
12
22
  export declare function onRenderClient(pageContext: ClientPageContext): Promise<void>;
23
+ /**
24
+ * Factory to create a customized onRenderClient hook.
25
+ *
26
+ * ```typescript
27
+ * // pages/+onRenderClient.ts
28
+ * import { createOnRenderClient } from '@llui/vike/client'
29
+ *
30
+ * export const onRenderClient = createOnRenderClient({
31
+ * container: '#root',
32
+ * onMount: () => console.log('Page ready'),
33
+ * })
34
+ * ```
35
+ */
36
+ export declare function createOnRenderClient(options: RenderClientOptions): (pageContext: ClientPageContext) => Promise<void>;
13
37
  //# sourceMappingURL=on-render-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"on-render-client.d.ts","sourceRoot":"","sources":["../src/on-render-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAE7C,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,cAAc,CAAC,EAAE,OAAO,CAAA;KACzB;CACF;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACtD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,wBAAsB,cAAc,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAUlF"}
1
+ {"version":3,"file":"on-render-client.d.ts","sourceRoot":"","sources":["../src/on-render-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAa,MAAM,WAAW,CAAA;AAExD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,cAAc,CAAC,EAAE,OAAO,CAAA;KACzB;CACF;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACtD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAKD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAElF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,mBAAmB,GAC3B,CAAC,WAAW,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAEnD"}
@@ -1,13 +1,51 @@
1
1
  import { hydrateApp, mountApp } from '@llui/dom';
2
+ // Track the current app handle so we can dispose it on client navigation
3
+ let currentHandle = null;
4
+ /**
5
+ * Default onRenderClient hook.
6
+ * Hydrates if isHydration is true, otherwise mounts fresh.
7
+ */
2
8
  export async function onRenderClient(pageContext) {
9
+ renderClient(pageContext, {});
10
+ }
11
+ /**
12
+ * Factory to create a customized onRenderClient hook.
13
+ *
14
+ * ```typescript
15
+ * // pages/+onRenderClient.ts
16
+ * import { createOnRenderClient } from '@llui/vike/client'
17
+ *
18
+ * export const onRenderClient = createOnRenderClient({
19
+ * container: '#root',
20
+ * onMount: () => console.log('Page ready'),
21
+ * })
22
+ * ```
23
+ */
24
+ export function createOnRenderClient(options) {
25
+ return (pageContext) => renderClient(pageContext, options);
26
+ }
27
+ async function renderClient(pageContext, options) {
3
28
  const { Page } = pageContext;
4
- const container = document.getElementById('app');
29
+ const selector = options.container ?? '#app';
30
+ const container = document.querySelector(selector);
31
+ if (!container) {
32
+ throw new Error(`@llui/vike: container "${selector}" not found in DOM`);
33
+ }
34
+ // Dispose previous page's component on client navigation
35
+ if (currentHandle) {
36
+ currentHandle.dispose();
37
+ currentHandle = null;
38
+ }
39
+ const el = container;
5
40
  if (pageContext.isHydration) {
6
41
  const serverState = window.__LLUI_STATE__;
7
- hydrateApp(container, Page, serverState);
42
+ currentHandle = hydrateApp(el, Page, serverState);
8
43
  }
9
44
  else {
10
- mountApp(container, Page, pageContext.data);
45
+ // Clear old DOM before mounting new page
46
+ el.textContent = '';
47
+ currentHandle = mountApp(el, Page, pageContext.data);
11
48
  }
49
+ options.onMount?.();
12
50
  }
13
51
  //# sourceMappingURL=on-render-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"on-render-client.js","sourceRoot":"","sources":["../src/on-render-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAehD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,WAA8B;IACjE,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,CAAA;IAC5B,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAE,CAAA;IAEjD,IAAI,WAAW,CAAC,WAAW,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,CAAA;QACzC,UAAU,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,CAAA;IAC1C,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,CAAA;IAC7C,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"on-render-client.js","sourceRoot":"","sources":["../src/on-render-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAsBhD,yEAAyE;AACzE,IAAI,aAAa,GAAqB,IAAI,CAAA;AAE1C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,WAA8B;IACjE,YAAY,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;AAC/B,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAA4B;IAE5B,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;AAC5D,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,WAA8B,EAC9B,OAA4B;IAE5B,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,CAAA;IAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,CAAA;IAC5C,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;IAElD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,oBAAoB,CAAC,CAAA;IACzE,CAAC;IAED,yDAAyD;IACzD,IAAI,aAAa,EAAE,CAAC;QAClB,aAAa,CAAC,OAAO,EAAE,CAAA;QACvB,aAAa,GAAG,IAAI,CAAA;IACtB,CAAC;IAED,MAAM,EAAE,GAAG,SAAwB,CAAA;IAEnC,IAAI,WAAW,CAAC,WAAW,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,CAAA;QACzC,aAAa,GAAG,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,CAAA;IACnD,CAAC;SAAM,CAAC;QACN,yCAAyC;QACzC,EAAE,CAAC,WAAW,GAAG,EAAE,CAAA;QACnB,aAAa,GAAG,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,CAAA;IACtD,CAAC;IAED,OAAO,CAAC,OAAO,EAAE,EAAE,CAAA;AACrB,CAAC"}
@@ -2,11 +2,49 @@ import type { ComponentDef } from '@llui/dom';
2
2
  export interface PageContext {
3
3
  Page: ComponentDef<unknown, unknown, unknown, unknown>;
4
4
  data?: unknown;
5
+ head?: string;
5
6
  }
6
- export declare function onRenderHtml(pageContext: PageContext): Promise<{
7
- documentHtml: string;
7
+ export interface DocumentContext {
8
+ /** Rendered component HTML */
9
+ html: string;
10
+ /** JSON-serialized initial state */
11
+ state: string;
12
+ /** Head content from pageContext.head (e.g. from +Head.ts) */
13
+ head: string;
14
+ /** Full page context for custom logic */
15
+ pageContext: PageContext;
16
+ }
17
+ export interface RenderHtmlResult {
18
+ documentHtml: string | {
19
+ _escaped: string;
20
+ };
8
21
  pageContext: {
9
22
  lluiState: unknown;
10
23
  };
11
- }>;
24
+ }
25
+ /**
26
+ * Default onRenderHtml hook for simple cases.
27
+ * Uses a minimal HTML document template.
28
+ */
29
+ export declare function onRenderHtml(pageContext: PageContext): Promise<RenderHtmlResult>;
30
+ /**
31
+ * Factory to create a customized onRenderHtml hook.
32
+ *
33
+ * ```typescript
34
+ * // pages/+onRenderHtml.ts
35
+ * import { createOnRenderHtml } from '@llui/vike'
36
+ *
37
+ * export const onRenderHtml = createOnRenderHtml({
38
+ * document: ({ html, state, head }) => `<!DOCTYPE html>
39
+ * <html>
40
+ * <head>${head}<link rel="stylesheet" href="/styles.css" /></head>
41
+ * <body><div id="app">${html}</div>
42
+ * <script>window.__LLUI_STATE__ = ${state}</script></body>
43
+ * </html>`,
44
+ * })
45
+ * ```
46
+ */
47
+ export declare function createOnRenderHtml(options: {
48
+ document: (ctx: DocumentContext) => string;
49
+ }): (pageContext: PageContext) => Promise<RenderHtmlResult>;
12
50
  //# sourceMappingURL=on-render-html.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"on-render-html.d.ts","sourceRoot":"","sources":["../src/on-render-html.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAE7C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACtD,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,wBAAsB,YAAY,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC;IACpE,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAA;CACpC,CAAC,CAiBD"}
1
+ {"version":3,"file":"on-render-html.d.ts","sourceRoot":"","sources":["../src/on-render-html.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAE7C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACtD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,yCAAyC;IACzC,WAAW,EAAE,WAAW,CAAA;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3C,WAAW,EAAE;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAA;CACpC;AAcD;;;GAGG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAEtF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,QAAQ,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,MAAM,CAAA;CAC3C,GAAG,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAE1D"}
@@ -1,18 +1,56 @@
1
1
  import { renderToString } from '@llui/dom';
2
+ const DEFAULT_DOCUMENT = ({ html, state, head }) => `<!DOCTYPE html>
3
+ <html>
4
+ <head>
5
+ <meta charset="utf-8" />
6
+ ${head}
7
+ </head>
8
+ <body>
9
+ <div id="app">${html}</div>
10
+ <script>window.__LLUI_STATE__ = ${state}</script>
11
+ </body>
12
+ </html>`;
13
+ /**
14
+ * Default onRenderHtml hook for simple cases.
15
+ * Uses a minimal HTML document template.
16
+ */
2
17
  export async function onRenderHtml(pageContext) {
18
+ return renderPage(pageContext, DEFAULT_DOCUMENT);
19
+ }
20
+ /**
21
+ * Factory to create a customized onRenderHtml hook.
22
+ *
23
+ * ```typescript
24
+ * // pages/+onRenderHtml.ts
25
+ * import { createOnRenderHtml } from '@llui/vike'
26
+ *
27
+ * export const onRenderHtml = createOnRenderHtml({
28
+ * document: ({ html, state, head }) => `<!DOCTYPE html>
29
+ * <html>
30
+ * <head>${head}<link rel="stylesheet" href="/styles.css" /></head>
31
+ * <body><div id="app">${html}</div>
32
+ * <script>window.__LLUI_STATE__ = ${state}</script></body>
33
+ * </html>`,
34
+ * })
35
+ * ```
36
+ */
37
+ export function createOnRenderHtml(options) {
38
+ return (pageContext) => renderPage(pageContext, options.document);
39
+ }
40
+ async function renderPage(pageContext, document) {
41
+ // Lazy-import to keep jsdom out of the client bundle's dependency graph
42
+ const { initSsrDom } = await import('@llui/dom/ssr');
43
+ await initSsrDom();
3
44
  const { Page, data } = pageContext;
4
45
  const [initialState] = Page.init(data);
5
46
  const html = renderToString(Page, initialState);
6
- const serializedState = JSON.stringify(initialState);
47
+ const state = JSON.stringify(initialState);
48
+ const head = pageContext.head ?? '';
49
+ const documentHtml = document({ html, state, head, pageContext });
7
50
  return {
8
- documentHtml: `<!DOCTYPE html>
9
- <html>
10
- <head><meta charset="utf-8" /></head>
11
- <body>
12
- <div id="app">${html}</div>
13
- <script>window.__LLUI_STATE__ = ${serializedState}</script>
14
- </body>
15
- </html>`,
51
+ // Use Vike's dangerouslySkipEscape format — the document template
52
+ // is trusted (authored by the developer, not user input)
53
+ documentHtml: { _escaped: documentHtml },
16
54
  pageContext: { lluiState: initialState },
17
55
  };
18
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"on-render-html.js","sourceRoot":"","sources":["../src/on-render-html.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAQ1C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,WAAwB;IAIzD,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,WAAW,CAAA;IAClC,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACtC,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;IAC/C,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA;IAEpD,OAAO;QACL,YAAY,EAAE;;;;oBAIE,IAAI;sCACc,eAAe;;QAE7C;QACJ,WAAW,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE;KACzC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"on-render-html.js","sourceRoot":"","sources":["../src/on-render-html.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAyB1C,MAAM,gBAAgB,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAmB,EAAU,EAAE,CAAC;;;;MAIvE,IAAI;;;oBAGU,IAAI;sCACc,KAAK;;QAEnC,CAAA;AAER;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,WAAwB;IACzD,OAAO,UAAU,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAA;AAClD,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAElC;IACC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;AACnE,CAAC;AAED,KAAK,UAAU,UAAU,CACvB,WAAwB,EACxB,QAA0C;IAE1C,wEAAwE;IACxE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;IACpD,MAAM,UAAU,EAAE,CAAA;IAElB,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,WAAW,CAAA;IAClC,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACtC,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA;IAC1C,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,IAAI,EAAE,CAAA;IAEnC,MAAM,YAAY,GAAG,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;IAEjE,OAAO;QACL,kEAAkE;QAClE,yDAAyD;QACzD,YAAY,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE;QACxC,WAAW,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE;KACzC,CAAA;AACH,CAAC"}
package/package.json CHANGED
@@ -1,12 +1,20 @@
1
1
  {
2
2
  "name": "@llui/vike",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "exports": {
7
7
  ".": {
8
8
  "types": "./dist/index.d.ts",
9
9
  "import": "./dist/index.js"
10
+ },
11
+ "./client": {
12
+ "types": "./dist/on-render-client.d.ts",
13
+ "import": "./dist/on-render-client.js"
14
+ },
15
+ "./server": {
16
+ "types": "./dist/on-render-html.d.ts",
17
+ "import": "./dist/on-render-html.js"
10
18
  }
11
19
  },
12
20
  "files": [
@@ -20,7 +28,8 @@
20
28
  "test:coverage": "vitest run --coverage"
21
29
  },
22
30
  "dependencies": {
23
- "@llui/dom": "workspace:*"
31
+ "@llui/dom": "workspace:*",
32
+ "jsdom": "^26.1.0"
24
33
  },
25
34
  "description": "LLui Vike SSR adapter — onRenderHtml, onRenderClient hooks",
26
35
  "keywords": [