vike-lite-react 1.0.1 → 1.0.3

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,4 +1,5 @@
1
- # vike-lite-react
1
+ # Vike Lite React
2
+ <a href="https://npmjs.com/package/vike-lite-react"><img src="https://img.shields.io/npm/v/vike-lite-react.svg" alt="npm package"></a>
2
3
 
3
4
  The official React integration for `vike-lite`. It provides seamless Server-Side Rendering (SSR), Static Site Generation (SSG), and client hydration out of the box, with a focus on minimalism and performance.
4
5
 
@@ -19,7 +20,7 @@ yarn add -D vike-lite-react @vitejs/plugin-react
19
20
  yarn add react react-dom
20
21
  ```
21
22
 
22
- ### ⚙️ Vite Plugin
23
+ ### 🛠️ Vite Plugin
23
24
 
24
25
  ```ts
25
26
  // vite.config.ts
@@ -141,7 +142,7 @@ Why choose `vike-lite`? It's built to be as minimal and fast as possible. Here a
141
142
  | **Reactivity Architecture** | _Single Source of Truth_ | _Separation of Concerns_ | `vike-lite-react` keeps page data (`pageContext`) and the active UI (`view`: Page/Layout/Head) as two separate `useState` atoms, so a data update doesn't force React to re-resolve which components are mounted, and vice versa.
142
143
  | **Accessibility (A11y)** | _Not_ handled by default | _Automatic_ handled | After a client-side navigation, `vike-lite-react` moves the focus to `#root`. This significantly improves UX for keyboard navigation and screen readers.
143
144
  | `useData()` **Hook** | `getter` only | `[getter, setter]` | `vike-lite-react` allows you to mutate the route data locally without needing other state managers.
144
- | URL parsed | manual `new URL(pageContext.urlOriginal)` | [useUrl()](#useurl) | A dedicated hook, consistent with `vike-lite-solid`.
145
+ | URL parsed | [pageContext.urlParsed](https://vike.dev/pageContext#urlParsed) | [useUrl()](#useurl) | A dedicated hook, consistent with `vike-lite-react`
145
146
 
146
147
  ---
147
148
 
@@ -0,0 +1,9 @@
1
+ import { t as PageContextReactContext } from "./globalContext-BIY5-Fdk.mjs";
2
+ //#region src/hooks/PageContextProvider.tsx
3
+ function PageContextProvider({ value, children }) {
4
+ return <PageContextReactContext.Provider value={value}>
5
+ {children}
6
+ </PageContextReactContext.Provider>;
7
+ }
8
+ //#endregion
9
+ export { PageContextProvider as t };
@@ -0,0 +1,8 @@
1
+ import { VikeState } from "vike-lite/__internal/server";
2
+ //#region src/__internal/client/onRenderClient.d.ts
3
+ declare function onRenderClient(clientOptions: {
4
+ routes: VikeState['routes'];
5
+ errorRoute: VikeState['errorRoute'];
6
+ }): Promise<void>;
7
+ //#endregion
8
+ export { onRenderClient as default };
@@ -0,0 +1,299 @@
1
+ import { t as PageContextProvider } from "../../PageContextProvider-Dec19bRR.mjs";
2
+ import { Component, useCallback, useEffect, useMemo, useRef, useState } from "react";
3
+ import { createRoot, hydrateRoot } from "react-dom/client";
4
+ import { matchRoute } from "vike-lite/__internal/shared";
5
+ import { hydration } from "virtual:vike-lite/config";
6
+ //#region src/__internal/shared/stripBase.ts
7
+ function stripBase(pathname) {
8
+ const { BASE_URL } = import.meta.env;
9
+ if (BASE_URL === "/" || !pathname.startsWith(BASE_URL)) return pathname;
10
+ const stripped = pathname.slice(BASE_URL.length);
11
+ return stripped.startsWith("/") ? stripped : "/" + stripped;
12
+ }
13
+ //#endregion
14
+ //#region src/__internal/client/onRenderClient.tsx
15
+ var RootErrorBoundary = class extends Component {
16
+ static getDerivedStateFromError(error) {
17
+ return { error };
18
+ }
19
+ state = { error: null };
20
+ render() {
21
+ if (this.state.error) return <div>Error: {this.state.error.message}</div>;
22
+ return this.props.children;
23
+ }
24
+ };
25
+ function RouterApp(props) {
26
+ const [pageContext, setPageContextState] = useState(props.initialContext);
27
+ const [view, setView] = useState(props.initialView);
28
+ const [currentUrl, setCurrentUrl] = useState(props.initialUrl);
29
+ const [currentPathname, setCurrentPathname] = useState(props.initialContext.urlPathname);
30
+ const [reloadTick, setReloadTick] = useState(0);
31
+ const shouldScrollToTop = useRef(false);
32
+ const pendingContextOverride = useRef(null);
33
+ const reloadResolvers = useRef([]);
34
+ const isFirstRun = useRef(true);
35
+ const setPageContext = useCallback((updater) => {
36
+ setPageContextState(updater);
37
+ }, []);
38
+ const matchedRoute = useMemo(() => matchRoute(currentPathname, props.routes), [currentPathname, props.routes]);
39
+ useEffect(() => {
40
+ const handleLinkClick = (e) => {
41
+ const target = e.target.closest("a");
42
+ if (!target?.href || target.target === "_blank" || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey) return;
43
+ const url = new URL(target.href);
44
+ if (url.origin !== globalThis.location.origin) return;
45
+ if (url.pathname === globalThis.location.pathname && url.search === globalThis.location.search) return;
46
+ e.preventDefault();
47
+ globalThis.history.pushState({ triggeredBy: "vike-lite" }, "", url.href);
48
+ if (!url.hash) shouldScrollToTop.current = true;
49
+ setCurrentUrl(url.href);
50
+ setCurrentPathname(stripBase(url.pathname));
51
+ };
52
+ const prefetchedModules = /* @__PURE__ */ new Set();
53
+ function prefetchRoute(route) {
54
+ const modules = [
55
+ [route.page, route.Page],
56
+ [route.layout, route.Layout],
57
+ [route.head, route.Head]
58
+ ];
59
+ for (const [key, loader] of modules) {
60
+ if (!key || !loader || prefetchedModules.has(key)) continue;
61
+ prefetchedModules.add(key);
62
+ loader().catch(() => {
63
+ prefetchedModules.delete(key);
64
+ });
65
+ }
66
+ }
67
+ const handleLinkPrefetch = (e) => {
68
+ const target = e.target.closest("a");
69
+ if (!target?.href) return;
70
+ if (target.target && target.target !== "_self") return;
71
+ if (target.hasAttribute("download")) return;
72
+ const url = new URL(target.href);
73
+ if (url.origin !== globalThis.location.origin) return;
74
+ if (url.pathname === globalThis.location.pathname && url.search === globalThis.location.search) return;
75
+ const matched = matchRoute(stripBase(url.pathname), props.routes);
76
+ if (!matched) return;
77
+ prefetchRoute(matched.route);
78
+ };
79
+ const handlePopState = () => {
80
+ setCurrentUrl(globalThis.location.href);
81
+ setCurrentPathname(stripBase(globalThis.location.pathname));
82
+ };
83
+ const handleProgrammaticNavigate = (e) => {
84
+ const detail = e.detail || {};
85
+ if (!detail.keepScrollPosition) shouldScrollToTop.current = true;
86
+ if (detail.pageContext) pendingContextOverride.current = detail.pageContext;
87
+ setCurrentUrl(globalThis.location.href);
88
+ setCurrentPathname(stripBase(globalThis.location.pathname));
89
+ };
90
+ const handleProgrammaticReload = (e) => {
91
+ const resolve = e.detail?.resolve;
92
+ if (resolve) reloadResolvers.current.push(resolve);
93
+ setReloadTick((t) => t + 1);
94
+ };
95
+ document.addEventListener("click", handleLinkClick);
96
+ document.addEventListener("pointerenter", handleLinkPrefetch, { capture: true });
97
+ document.addEventListener("focusin", handleLinkPrefetch);
98
+ globalThis.addEventListener("popstate", handlePopState);
99
+ globalThis.addEventListener("vike-navigate", handleProgrammaticNavigate);
100
+ globalThis.addEventListener("vike-reload", handleProgrammaticReload);
101
+ return () => {
102
+ document.removeEventListener("click", handleLinkClick);
103
+ document.removeEventListener("pointerenter", handleLinkPrefetch, { capture: true });
104
+ document.removeEventListener("focusin", handleLinkPrefetch);
105
+ globalThis.removeEventListener("popstate", handlePopState);
106
+ globalThis.removeEventListener("vike-navigate", handleProgrammaticNavigate);
107
+ globalThis.removeEventListener("vike-reload", handleProgrammaticReload);
108
+ };
109
+ }, [props.routes]);
110
+ useEffect(() => {
111
+ const pathname = currentPathname;
112
+ const isReload = reloadTick > 0;
113
+ if (isFirstRun.current && !isReload && globalThis.__PAGE_CONTEXT__?.urlPathname === pathname) {
114
+ isFirstRun.current = false;
115
+ globalThis.__PAGE_CONTEXT__.urlPathname = void 0;
116
+ return;
117
+ }
118
+ isFirstRun.current = false;
119
+ const controller = new AbortController();
120
+ const signal = controller.signal;
121
+ const urlFull = currentUrl;
122
+ const matched = matchedRoute;
123
+ const loadRoute = async () => {
124
+ const contextOverride = pendingContextOverride.current;
125
+ pendingContextOverride.current = null;
126
+ function finalizeNavigation() {
127
+ if (shouldScrollToTop.current) {
128
+ globalThis.scrollTo(0, 0);
129
+ shouldScrollToTop.current = false;
130
+ } else if (globalThis.location.hash) requestAnimationFrame(() => {
131
+ try {
132
+ document.querySelector(decodeURIComponent(globalThis.location.hash))?.scrollIntoView();
133
+ } catch {}
134
+ });
135
+ }
136
+ const renderErrorPage = async (is404, message) => {
137
+ if (!props.errorRoute) return;
138
+ const [ErrorPageMod, ErrorLayoutMod, ErrorHeadMod] = await Promise.all([
139
+ props.errorRoute.Page(),
140
+ props.errorRoute.Layout?.() ?? null,
141
+ props.errorRoute.Head?.() ?? null
142
+ ]);
143
+ if (signal.aborted) return;
144
+ setPageContext(() => ({
145
+ urlOriginal: urlFull,
146
+ urlPathname: pathname,
147
+ routeParams: {},
148
+ is404,
149
+ is500: !is404,
150
+ errorMessage: message,
151
+ isClientSide: true,
152
+ isHydration: false
153
+ }));
154
+ setView({
155
+ Page: ErrorPageMod.Page ?? ErrorPageMod.default,
156
+ Layout: ErrorLayoutMod?.Layout ?? ErrorLayoutMod?.default ?? null,
157
+ Head: ErrorHeadMod?.Head ?? ErrorHeadMod?.default ?? null
158
+ });
159
+ document.title = is404 ? "Not Found" : "Server Error";
160
+ finalizeNavigation();
161
+ };
162
+ if (!matched) return renderErrorPage(true);
163
+ const { route, routeParams } = matched;
164
+ try {
165
+ const urlObj = new URL(urlFull);
166
+ const jsonTarget = pathname === "/" ? "/index" : pathname;
167
+ const { BASE_URL } = import.meta.env;
168
+ const jsonUrl = `${BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL}${jsonTarget}.pageContext.json${urlObj.search}`;
169
+ let ctx = null;
170
+ if (route.data || route.title) {
171
+ const res = await fetch(jsonUrl, {
172
+ signal,
173
+ cache: isReload ? "no-cache" : "default"
174
+ });
175
+ const contentType = res.headers.get("content-type") ?? "";
176
+ if (!contentType.includes("application/json")) throw new Error(`Expected JSON but got "${contentType}" for ${jsonUrl}. Check your proxy/CDN configuration.`);
177
+ ctx = await res.json();
178
+ }
179
+ if (signal.aborted) return;
180
+ if (ctx?._redirect) {
181
+ const urlObjRedirect = new URL(ctx._redirect, globalThis.location.origin);
182
+ if (urlObjRedirect.origin !== globalThis.location.origin) {
183
+ globalThis.location.assign(ctx._redirect);
184
+ return;
185
+ }
186
+ globalThis.history.pushState({ triggeredBy: "vike-lite" }, "", ctx._redirect);
187
+ shouldScrollToTop.current = true;
188
+ setCurrentUrl(urlObjRedirect.href);
189
+ setCurrentPathname(stripBase(urlObjRedirect.pathname));
190
+ return;
191
+ }
192
+ if (ctx && (ctx.is404 || ctx.is500 || ctx.isError)) return renderErrorPage(ctx.is404, ctx.reason || "Server Error");
193
+ const [PageMod, LayoutMod, HeadMod] = await Promise.all([
194
+ route.Page(),
195
+ route.Layout?.() ?? null,
196
+ route.Head?.() ?? null
197
+ ]);
198
+ if (signal.aborted) return;
199
+ setPageContext(() => ({
200
+ routeParams,
201
+ urlOriginal: urlObj.href,
202
+ urlPathname: pathname,
203
+ search: urlObj.search,
204
+ ...ctx?.data && { data: ctx.data },
205
+ ...ctx?.title && { title: ctx.title },
206
+ ...contextOverride,
207
+ isClientSide: true,
208
+ isHydration: false
209
+ }));
210
+ setView({
211
+ Page: PageMod.Page ?? PageMod.default,
212
+ Layout: LayoutMod?.Layout ?? LayoutMod?.default ?? null,
213
+ Head: HeadMod?.Head ?? HeadMod?.default ?? null
214
+ });
215
+ if (ctx?.title) document.title = ctx.title;
216
+ requestAnimationFrame(() => {
217
+ if (globalThis.location.hash) return;
218
+ document.querySelector("#root")?.focus({ preventScroll: true });
219
+ });
220
+ finalizeNavigation();
221
+ } catch (error) {
222
+ if (error.name === "AbortError") return;
223
+ const message = error.message || "";
224
+ if (/dynamically imported module|importing a module script failed/i.test(message)) {
225
+ const GUARD_KEY = "vike-lite:reload-guard";
226
+ const last = Number(sessionStorage.getItem(GUARD_KEY) ?? 0);
227
+ if (Date.now() - last > 1e4) {
228
+ sessionStorage.setItem(GUARD_KEY, String(Date.now()));
229
+ console.warn("App update detected, forcing reload…");
230
+ globalThis.location.assign(urlFull);
231
+ return;
232
+ }
233
+ }
234
+ console.error("Router Error:", error);
235
+ renderErrorPage(false, message);
236
+ } finally {
237
+ if (!signal.aborted) {
238
+ for (const resolve of reloadResolvers.current) resolve();
239
+ reloadResolvers.current = [];
240
+ }
241
+ }
242
+ };
243
+ loadRoute();
244
+ return () => controller.abort();
245
+ }, [
246
+ currentPathname,
247
+ currentUrl,
248
+ matchedRoute,
249
+ reloadTick
250
+ ]);
251
+ const { Page, Layout } = view;
252
+ const contextValue = useMemo(() => ({
253
+ pageContext,
254
+ setPageContext
255
+ }), [pageContext, setPageContext]);
256
+ return <RootErrorBoundary>
257
+ <PageContextProvider value={contextValue}>
258
+ {Layout ? <Layout><Page /></Layout> : <Page />}
259
+ </PageContextProvider>
260
+ </RootErrorBoundary>;
261
+ }
262
+ async function onRenderClient(clientOptions) {
263
+ const container = document.querySelector("#root");
264
+ const rawContext = globalThis.__PAGE_CONTEXT__ ?? {};
265
+ const isHydration = hydration && !!globalThis.__PAGE_CONTEXT__;
266
+ const initialContext = {
267
+ ...rawContext,
268
+ isClientSide: true,
269
+ isHydration
270
+ };
271
+ let initialView = {
272
+ Page: null,
273
+ Layout: null,
274
+ Head: null
275
+ };
276
+ if (isHydration) {
277
+ const matched = matchRoute(initialContext.urlPathname ?? globalThis.location.pathname, clientOptions.routes);
278
+ if (matched) {
279
+ const [PageMod, LayoutMod, HeadMod] = await Promise.all([
280
+ matched.route.Page(),
281
+ matched.route.Layout?.() ?? null,
282
+ matched.route.Head?.() ?? null
283
+ ]);
284
+ initialView = {
285
+ Page: PageMod.Page ?? PageMod.default,
286
+ Layout: LayoutMod?.Layout ?? LayoutMod?.default ?? null,
287
+ Head: HeadMod?.Head ?? HeadMod?.default ?? null
288
+ };
289
+ }
290
+ }
291
+ const app = <RouterApp {...clientOptions} initialView={initialView} initialContext={initialContext} initialUrl={globalThis.location.href} />;
292
+ if (isHydration) hydrateRoot(container, app);
293
+ else {
294
+ container.replaceChildren();
295
+ createRoot(container).render(app);
296
+ }
297
+ }
298
+ //#endregion
299
+ export { onRenderClient as default };
@@ -0,0 +1,13 @@
1
+ import { ComponentType, ReactNode } from "react";
2
+ import { RenderContext } from "vike-lite/__internal/shared";
3
+ //#region src/__internal/server/onRenderHtml.d.ts
4
+ interface ReactRenderContext extends RenderContext {
5
+ Page: ComponentType;
6
+ Head?: ComponentType;
7
+ Layout?: ComponentType<{
8
+ children: ReactNode;
9
+ }>;
10
+ }
11
+ declare function onRenderHtml({ pageContext, Page, Head, Layout, pageTitleTag, serializedContext, assets }: ReactRenderContext): string;
12
+ //#endregion
13
+ export { ReactRenderContext, onRenderHtml };
@@ -0,0 +1,33 @@
1
+ import { t as PageContextProvider } from "../../PageContextProvider-Dec19bRR.mjs";
2
+ import { renderToString } from "react-dom/server";
3
+ import { hydration } from "virtual:vike-lite/renderer";
4
+ //#region src/__internal/server/onRenderHtml.tsx
5
+ function onRenderHtml({ pageContext, Page, Head, Layout, pageTitleTag, serializedContext, assets }) {
6
+ const { cssLinks, jsPreloads, entryClient } = assets;
7
+ const providerValue = {
8
+ pageContext,
9
+ setPageContext: () => {}
10
+ };
11
+ return `<!DOCTYPE html>
12
+ <html lang="en">
13
+ <head>
14
+ <meta charset="utf-8">
15
+ <meta name="viewport" content="width=device-width,initial-scale=1">
16
+ ${pageTitleTag}
17
+ ${cssLinks}
18
+ ${jsPreloads}
19
+ ${Head ? renderToString(<PageContextProvider value={providerValue}>
20
+ <Head />
21
+ </PageContextProvider>) : ""}
22
+ <script>window.__PAGE_CONTEXT__=${serializedContext}<\/script>
23
+ </head>
24
+ <body>
25
+ <div id="root" tabindex="-1">${hydration ? renderToString(<PageContextProvider value={providerValue}>
26
+ {Layout ? <Layout><Page /></Layout> : <Page />}
27
+ </PageContextProvider>) : ""}</div>
28
+ <script type="module" src="${entryClient}"><\/script>
29
+ </body>
30
+ </html>`;
31
+ }
32
+ //#endregion
33
+ export { onRenderHtml };
@@ -0,0 +1,8 @@
1
+ import { createContext } from "react";
2
+ //#region src/hooks/globalContext.tsx
3
+ const KEY = "__vike_lite_react_context__";
4
+ const g = globalThis;
5
+ if (!Object.hasOwn(g, KEY)) g[KEY] = createContext(null);
6
+ const PageContextReactContext = g[KEY];
7
+ //#endregion
8
+ export { PageContextReactContext as t };
package/dist/index.mjs CHANGED
@@ -1,10 +1,5 @@
1
- import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
2
- //#region src/hooks/globalContext.tsx
3
- const KEY = "__vike_lite_react_context__";
4
- const g = globalThis;
5
- if (!Object.hasOwn(g, KEY)) g[KEY] = createContext(null);
6
- const PageContextReactContext = g[KEY];
7
- //#endregion
1
+ import { t as PageContextReactContext } from "./globalContext-BIY5-Fdk.mjs";
2
+ import { useCallback, useContext, useEffect, useMemo, useState } from "react";
8
3
  //#region src/hooks/useData.tsx
9
4
  function useData() {
10
5
  const ctx = useContext(PageContextReactContext);
package/dist/vite.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Options } from "@vitejs/plugin-react";
2
2
  import { Plugin } from "vite";
3
- //#region src/vite-plugin.d.ts
3
+ //#region src/vite.d.ts
4
4
  interface VikeLiteReactOptions {
5
5
  /**
6
6
  * Enable client hydration (SSR + hydrate) or full client takeover (SPA mode).
package/dist/vite.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import react from "@vitejs/plugin-react";
2
- //#region src/vite-plugin.ts
2
+ //#region src/vite.ts
3
3
  function vikeLiteReact({ hydration = true, react: reactOptions } = {}) {
4
4
  const virtualConfigId = "virtual:vike-lite/config";
5
5
  const virtualClientId = "virtual:vike-lite/client";
@@ -16,9 +16,9 @@ function vikeLiteReact({ hydration = true, react: reactOptions } = {}) {
16
16
  if (id === virtualServerId) return resolvedVirtualServerId;
17
17
  },
18
18
  load(id) {
19
- if (id === resolvedVirtualConfigId) return `export const hydration = ${JSON.stringify(hydration)};`;
19
+ if (id === resolvedVirtualConfigId) return `export const hydration=${hydration};`;
20
20
  if (id === resolvedVirtualClientId) return "export const onRenderClient=()=>import(\"vike-lite-react/__internal/client/onRenderClient\");";
21
- if (id === resolvedVirtualServerId) return `export { onRenderHtml } from 'vike-lite-react/__internal/server/onRenderHtml';`;
21
+ if (id === resolvedVirtualServerId) return `export {onRenderHtml}from'vike-lite-react/__internal/server/onRenderHtml';`;
22
22
  }
23
23
  };
24
24
  return [...react(reactOptions), adapter];
package/package.json CHANGED
@@ -1,7 +1,32 @@
1
1
  {
2
2
  "name": "vike-lite-react",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/node-ecosystem/vike-lite.git"
8
+ },
9
+ "homepage": "https://github.com/node-ecosystem/vike-lite#readme",
10
+ "bugs": {
11
+ "url": "https://github.com/node-ecosystem/vike-lite/issues"
12
+ },
13
+ "keywords": [
14
+ "framework",
15
+ "lite",
16
+ "react",
17
+ "react-ssr",
18
+ "server-side-rendering",
19
+ "ssg",
20
+ "ssr",
21
+ "static-site-generator",
22
+ "vike",
23
+ "vike-lite",
24
+ "vite",
25
+ "vite-plugin",
26
+ "vite-ssr",
27
+ "vitejs",
28
+ "web-framework"
29
+ ],
5
30
  "type": "module",
6
31
  "module": "./dist/index.mjs",
7
32
  "types": "./dist/index.d.mts",
@@ -15,22 +40,14 @@
15
40
  "import": "./dist/vite.mjs"
16
41
  },
17
42
  "./__internal/client/onRenderClient": {
18
- "types": "./src/__internal/client/onRenderClient.tsx",
19
- "import": "./src/__internal/client/onRenderClient.tsx"
43
+ "types": "./dist/__internal/client/onRenderClient.d.mts",
44
+ "import": "./dist/__internal/client/onRenderClient.mjs"
20
45
  },
21
46
  "./__internal/server/onRenderHtml": {
22
- "types": "./src/__internal/server/onRenderHtml.tsx",
23
- "import": "./src/__internal/server/onRenderHtml.tsx"
47
+ "types": "./dist/__internal/server/onRenderHtml.d.mts",
48
+ "import": "./dist/__internal/server/onRenderHtml.mjs"
24
49
  }
25
50
  },
26
- "repository": {
27
- "type": "git",
28
- "url": "git+https://github.com/node-ecosystem/vike-lite-react.git"
29
- },
30
- "homepage": "https://github.com/node-ecosystem/vike-lite-react#readme",
31
- "bugs": {
32
- "url": "https://github.com/node-ecosystem/vike-lite-react/issues"
33
- },
34
51
  "files": [
35
52
  "dist"
36
53
  ],
@@ -45,8 +62,8 @@
45
62
  "@vitejs/plugin-react": "^6.0.3",
46
63
  "react": "^19.2.7",
47
64
  "react-dom": "^19.2.7",
48
- "tsdown": "^0.22.5",
49
- "vike-lite": "1.13.2",
65
+ "tsdown": "^0.22.8",
66
+ "vike-lite": "1.15.1",
50
67
  "vite": "^8.1.4"
51
68
  },
52
69
  "peerDependencies": {