vike-lite 1.12.0 → 1.13.1

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.
@@ -1,4 +1,3 @@
1
- import { t as BASE_URL } from "../shared-DEpJkq09.mjs";
2
1
  //#region src/client/router.ts
3
2
  /**
4
3
  * Change page programmatically on the client without reloading the browser.
@@ -8,7 +7,10 @@ import { t as BASE_URL } from "../shared-DEpJkq09.mjs";
8
7
  function navigate(url, options) {
9
8
  if (typeof globalThis === "undefined") throw new Error("navigate() can only be called on the client side.");
10
9
  let finalUrl = url;
11
- if (finalUrl.startsWith("/")) finalUrl = (BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL) + (finalUrl === "/" ? "" : finalUrl);
10
+ if (finalUrl.startsWith("/")) {
11
+ const { BASE_URL } = import.meta.env;
12
+ finalUrl = (BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL) + (finalUrl === "/" ? "" : finalUrl);
13
+ }
12
14
  globalThis.history.pushState({ triggeredBy: "vike-lite" }, "", finalUrl);
13
15
  globalThis.dispatchEvent(new CustomEvent("vike-navigate", { detail: {
14
16
  keepScrollPosition: options?.keepScrollPosition,
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/index.d.ts
2
- type PageContextBase = {
2
+ type PageContextBase<Data = unknown> = {
3
3
  routeParams: Record<string, string>;
4
4
  urlOriginal: string;
5
5
  urlPathname: string;
@@ -8,19 +8,19 @@ type PageContextBase = {
8
8
  is404?: boolean;
9
9
  is500?: boolean;
10
10
  errorMessage?: string;
11
- };
12
- type PageContext<Data = unknown> = PageContextBase & (unknown extends Data ? {
11
+ } & (unknown extends Data ? {
13
12
  data?: Data;
14
13
  } : {
15
14
  data: Data;
16
15
  });
17
- type PageContextServer<Data = unknown> = PageContext<Data> & {
16
+ type PageContextServer<Data = unknown> = PageContextBase<Data> & {
18
17
  isClientSide: false;
19
18
  nonce?: string;
20
19
  };
21
- type PageContextClient = PageContextBase & {
20
+ type PageContextClient<Data = unknown> = PageContextBase<Data> & {
22
21
  isClientSide: true;
23
22
  isHydration?: boolean;
24
23
  };
24
+ type PageContext<Data = unknown> = PageContextServer<Data> | PageContextClient<Data>;
25
25
  //#endregion
26
26
  export { PageContext, PageContextClient, PageContextServer };
@@ -0,0 +1,220 @@
1
+ import { t as matchRoute } from "./matchRoute-nTNPxoMq.mjs";
2
+ import { AbortRedirect, AbortRender } from "./server/abort.mjs";
3
+ import { n as store } from "./store-DPJQje-K.mjs";
4
+ //#region src/utils/serializeContext.ts
5
+ const ESCAPE_LOOKUP = {
6
+ "&": String.raw`\u0026`,
7
+ ">": String.raw`\u003e`,
8
+ "<": String.raw`\u003c`,
9
+ "\u2028": String.raw`\u2028`,
10
+ "\u2029": String.raw`\u2029`
11
+ };
12
+ const ESCAPE_REGEX = /[&><\u{2028}\u{2029}]/gu;
13
+ function serializeContext(data) {
14
+ return JSON.stringify(data).replaceAll(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);
15
+ }
16
+ //#endregion
17
+ //#region src/server/renderPage.ts
18
+ const isProd = process.env.NODE_ENV === "production";
19
+ function withBase(file) {
20
+ const { BASE_URL } = import.meta.env;
21
+ return `${BASE_URL === "/" ? "" : BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL}${file.startsWith("/") ? file : `/${file}`}`;
22
+ }
23
+ const assetsCache = /* @__PURE__ */ new WeakMap();
24
+ function getAssets(route, nonce) {
25
+ if (!isProd) return computeAssets(route, nonce);
26
+ const nonceKey = nonce || "";
27
+ let routeCache = assetsCache.get(route);
28
+ if (!routeCache) {
29
+ routeCache = /* @__PURE__ */ new Map();
30
+ assetsCache.set(route, routeCache);
31
+ }
32
+ let assets = routeCache.get(nonceKey);
33
+ if (!assets) {
34
+ assets = computeAssets(route, nonce);
35
+ routeCache.set(nonceKey, assets);
36
+ }
37
+ return assets;
38
+ }
39
+ function computeAssets(route, nonce) {
40
+ if (!isProd) return {
41
+ cssLinks: "",
42
+ jsPreloads: "",
43
+ entryClient: withBase("@id/virtual:entry-client")
44
+ };
45
+ const cssFiles = /* @__PURE__ */ new Set();
46
+ const jsFiles = /* @__PURE__ */ new Map();
47
+ const { manifest } = store;
48
+ function getVirtualEntryClientKey() {
49
+ for (const key in manifest) if (manifest[key].isEntry) return key;
50
+ throw new Error("entry-client not found in manifest");
51
+ }
52
+ function collectAssets(key, isCritical) {
53
+ const chunk = manifest[key];
54
+ if (!chunk) return;
55
+ const current = jsFiles.get(chunk.file);
56
+ if (current === true) return;
57
+ if (current === false && !isCritical) return;
58
+ jsFiles.set(chunk.file, isCritical);
59
+ if (chunk.css) for (const css of chunk.css) cssFiles.add(css);
60
+ if (chunk.imports) for (const imp of chunk.imports) collectAssets(imp, false);
61
+ }
62
+ const virtualEntryClientKey = getVirtualEntryClientKey();
63
+ collectAssets(virtualEntryClientKey, true);
64
+ const { page, layout, head } = route;
65
+ collectAssets(page, true);
66
+ if (head) collectAssets(head, true);
67
+ if (layout) collectAssets(layout, true);
68
+ const criticalJs = [];
69
+ const sharedJs = [];
70
+ for (const [file, isCritical] of jsFiles) (isCritical ? criticalJs : sharedJs).push(file);
71
+ const nonceAttr = nonce ? ` nonce="${nonce}"` : "";
72
+ return {
73
+ cssLinks: [...cssFiles].map((href) => `<link rel="stylesheet" href="${withBase(href)}"${nonceAttr}>`).join(""),
74
+ jsPreloads: [...criticalJs.map((href) => `<link rel="modulepreload" href="${withBase(href)}" crossorigin fetchpriority="high"${nonceAttr}>`), ...sharedJs.map((href) => `<link rel="modulepreload" href="${withBase(href)}" crossorigin${nonceAttr}>`)].join(""),
75
+ entryClient: withBase(manifest[virtualEntryClientKey].file)
76
+ };
77
+ }
78
+ async function buildPageContext(urlPathname, urlOriginal, isJsonRequest) {
79
+ const matched = matchRoute(urlPathname, store.routes);
80
+ if (!matched) return null;
81
+ const { route, routeParams } = matched;
82
+ const pageContext = {
83
+ routeParams,
84
+ urlOriginal,
85
+ urlPathname
86
+ };
87
+ const [dataMod, titleMod, PageModule, HeadModule, LayoutModule] = await Promise.all([
88
+ route.Data?.() ?? null,
89
+ route.Title?.() ?? null,
90
+ isJsonRequest ? null : route.Page(),
91
+ isJsonRequest ? null : route.Head?.() ?? null,
92
+ isJsonRequest ? null : route.Layout?.() ?? null
93
+ ]);
94
+ if (dataMod) try {
95
+ pageContext.data = await (dataMod.data ?? dataMod.default)(pageContext);
96
+ } catch (error) {
97
+ console.error("+data hook failed at:", urlPathname);
98
+ throw error;
99
+ }
100
+ if (titleMod) try {
101
+ const titleFn = titleMod.title ?? titleMod.default;
102
+ pageContext.title = typeof titleFn === "function" ? titleFn(pageContext) : titleFn;
103
+ } catch (error) {
104
+ console.error("+title hook failed at:", urlPathname);
105
+ throw error;
106
+ }
107
+ return {
108
+ pageContext,
109
+ route,
110
+ PageModule,
111
+ HeadModule,
112
+ LayoutModule
113
+ };
114
+ }
115
+ async function renderErrorPage(req, status, urlPathname, error, nonce) {
116
+ let errorMessage;
117
+ let is500;
118
+ if (status === 500) {
119
+ console.error(`[vike-lite] Server Error:`, error);
120
+ errorMessage = isProd ? "Internal Server Error" : error instanceof Error ? error.message : "Unknown error";
121
+ is500 = true;
122
+ } else is500 = false;
123
+ if (!store.errorRoute) return new Response(status === 404 ? "Not Found" : "Internal Server Error", { status });
124
+ try {
125
+ const { default: onRenderHtml } = await store.config.onRenderHtml();
126
+ const [PageModule, HeadModule, LayoutModule] = await Promise.all([
127
+ store.errorRoute.Page(),
128
+ store.errorRoute.Head?.() ?? null,
129
+ store.errorRoute.Layout?.() ?? null
130
+ ]);
131
+ const pageContext = {
132
+ urlOriginal: req.url,
133
+ urlPathname,
134
+ routeParams: {},
135
+ is404: status === 404,
136
+ is500,
137
+ errorMessage
138
+ };
139
+ const html = await onRenderHtml({
140
+ pageContext,
141
+ Page: PageModule.Page ?? PageModule.default,
142
+ Layout: LayoutModule ? LayoutModule.Layout ?? LayoutModule.default : void 0,
143
+ Head: HeadModule ? HeadModule.Head ?? HeadModule.default : void 0,
144
+ pageTitleTag: `<title>${status === 404 ? "Page Not Found" : "Server Error"}</title>`,
145
+ serializedContext: serializeContext(pageContext),
146
+ assets: getAssets(store.errorRoute, nonce),
147
+ nonce
148
+ });
149
+ return new Response(html, {
150
+ status,
151
+ headers: { "Content-Type": "text/html" }
152
+ });
153
+ } catch (renderError) {
154
+ console.error("[vike-lite] Error page render failed:", renderError);
155
+ return new Response(status === 404 ? "Not Found" : "Internal Server Error", { status });
156
+ }
157
+ }
158
+ async function renderPage(req, { nonce } = {}) {
159
+ let { pathname } = new URL(req.url);
160
+ const { BASE_URL } = import.meta.env;
161
+ if (BASE_URL !== "/") {
162
+ const baseSlashed = BASE_URL.endsWith("/") ? BASE_URL : BASE_URL + "/";
163
+ const baseNoSlash = baseSlashed.slice(0, -1);
164
+ pathname = pathname === baseNoSlash ? "/" : pathname.slice(baseSlashed.length - 1);
165
+ }
166
+ const isJsonRequest = pathname.endsWith(".pageContext.json");
167
+ let targetPathname = pathname;
168
+ if (isJsonRequest) {
169
+ targetPathname = targetPathname.replace(/\.pageContext\.json$/, "");
170
+ if (targetPathname === "/index") targetPathname = "/";
171
+ }
172
+ try {
173
+ const resolved = await buildPageContext(targetPathname, req.url, isJsonRequest);
174
+ if (!resolved) {
175
+ if (isJsonRequest) return Response.json({ is404: true }, { status: 404 });
176
+ return renderErrorPage(req, 404, targetPathname, nonce);
177
+ }
178
+ const { pageContext, route, PageModule, HeadModule, LayoutModule } = resolved;
179
+ if (isJsonRequest) return Response.json(pageContext);
180
+ const { default: onRenderHtml } = await store.config.onRenderHtml();
181
+ const html = await onRenderHtml({
182
+ pageContext,
183
+ Page: PageModule.Page ?? PageModule.default,
184
+ Head: HeadModule ? HeadModule.Head ?? HeadModule.default : void 0,
185
+ Layout: LayoutModule ? LayoutModule.Layout ?? LayoutModule.default : void 0,
186
+ pageTitleTag: pageContext.title ? `<title>${pageContext.title}</title>` : "",
187
+ serializedContext: serializeContext(pageContext),
188
+ assets: getAssets(route, nonce),
189
+ nonce
190
+ });
191
+ return new Response(html, {
192
+ status: 200,
193
+ headers: { "Content-Type": "text/html" }
194
+ });
195
+ } catch (error) {
196
+ if (error instanceof AbortRedirect) {
197
+ let redirectUrl = error.url;
198
+ if (redirectUrl.startsWith("/")) redirectUrl = (BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL) + (redirectUrl === "/" ? "" : redirectUrl);
199
+ if (isJsonRequest) return Response.json({ _redirect: redirectUrl }, { status: 200 });
200
+ return new Response(null, {
201
+ status: error.statusCode,
202
+ headers: { Location: redirectUrl }
203
+ });
204
+ }
205
+ if (error instanceof AbortRender) {
206
+ if (isJsonRequest) return Response.json({
207
+ is404: error.statusCode === 404,
208
+ is500: error.statusCode >= 500,
209
+ isError: true,
210
+ reason: error.reason
211
+ }, { status: error.statusCode });
212
+ return renderErrorPage(req, error.statusCode, targetPathname, error.reason, nonce);
213
+ }
214
+ console.error("Render Error:", error);
215
+ if (isJsonRequest) return Response.json({ is500: true }, { status: 500 });
216
+ return renderErrorPage(req, 500, targetPathname, error, nonce);
217
+ }
218
+ }
219
+ //#endregion
220
+ export { renderPage as t };
package/dist/server.mjs CHANGED
@@ -1,196 +1,2 @@
1
- import { t as BASE_URL } from "./shared-DEpJkq09.mjs";
2
- import { t as matchRoute } from "./matchRoute-nTNPxoMq.mjs";
3
- import { AbortRedirect, AbortRender } from "./server/abort.mjs";
4
- import { n as store } from "./store-DPJQje-K.mjs";
5
- //#region src/utils/serializeContext.ts
6
- const ESCAPE_LOOKUP = {
7
- "&": String.raw`\u0026`,
8
- ">": String.raw`\u003e`,
9
- "<": String.raw`\u003c`,
10
- "\u2028": String.raw`\u2028`,
11
- "\u2029": String.raw`\u2029`
12
- };
13
- const ESCAPE_REGEX = /[&><\u{2028}\u{2029}]/gu;
14
- function serializeContext(data) {
15
- return JSON.stringify(data).replaceAll(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);
16
- }
17
- //#endregion
18
- //#region src/server/renderPage.ts
19
- const isProd = process.env.NODE_ENV === "production";
20
- function withBase(file) {
21
- return `${BASE_URL.replace(/\/$/, "")}/${file.replace(/^\//, "")}`;
22
- }
23
- function getAssets(route, nonce) {
24
- if (!isProd) return {
25
- cssLinks: "",
26
- jsPreloads: "",
27
- entryClient: withBase("@id/virtual:entry-client")
28
- };
29
- const cssFiles = /* @__PURE__ */ new Set();
30
- const jsFiles = /* @__PURE__ */ new Map();
31
- const { manifest } = store;
32
- function getVirtualEntryClientKey() {
33
- for (const key in manifest) if (manifest[key].isEntry) return key;
34
- throw new Error("entry-client not found in manifest");
35
- }
36
- function collectAssets(key, isCritical) {
37
- const chunk = manifest[key];
38
- if (!chunk) return;
39
- const current = jsFiles.get(chunk.file);
40
- if (current === true) return;
41
- if (current === false && !isCritical) return;
42
- jsFiles.set(chunk.file, isCritical);
43
- if (chunk.css) for (const css of chunk.css) cssFiles.add(css);
44
- if (chunk.imports) for (const imp of chunk.imports) collectAssets(imp, false);
45
- }
46
- const virtualEntryClientKey = getVirtualEntryClientKey();
47
- collectAssets(virtualEntryClientKey, true);
48
- const { page, layout, head } = route;
49
- collectAssets(page, true);
50
- if (head) collectAssets(head, true);
51
- if (layout) collectAssets(layout, true);
52
- const criticalJs = [];
53
- const sharedJs = [];
54
- for (const [file, isCritical] of jsFiles) (isCritical ? criticalJs : sharedJs).push(file);
55
- const nonceAttr = nonce ? ` nonce="${nonce}"` : "";
56
- return {
57
- cssLinks: [...cssFiles].map((href) => `<link rel="stylesheet" href="${withBase(href)}"${nonceAttr}>`).join(""),
58
- jsPreloads: [...criticalJs.map((href) => `<link rel="modulepreload" href="${withBase(href)}" crossorigin fetchpriority="high"${nonceAttr}>`), ...sharedJs.map((href) => `<link rel="modulepreload" href="${withBase(href)}" crossorigin${nonceAttr}>`)].join(""),
59
- entryClient: withBase(manifest[virtualEntryClientKey].file)
60
- };
61
- }
62
- async function buildPageContext(urlPathname, urlOriginal, isJsonRequest) {
63
- const matched = matchRoute(urlPathname, store.routes);
64
- if (!matched) return null;
65
- const { route, routeParams } = matched;
66
- const pageContext = {
67
- routeParams,
68
- urlOriginal,
69
- urlPathname
70
- };
71
- const [dataMod, titleMod, PageModule, HeadModule, LayoutModule] = await Promise.all([
72
- route.Data?.() ?? null,
73
- route.Title?.() ?? null,
74
- isJsonRequest ? null : route.Page(),
75
- isJsonRequest ? null : route.Head?.() ?? null,
76
- isJsonRequest ? null : route.Layout?.() ?? null
77
- ]);
78
- if (dataMod) try {
79
- pageContext.data = await (dataMod.data ?? dataMod.default)(pageContext);
80
- } catch (error) {
81
- console.error("+data hook failed at:", urlPathname);
82
- throw error;
83
- }
84
- if (titleMod) try {
85
- const titleFn = titleMod.title ?? titleMod.default;
86
- pageContext.title = typeof titleFn === "function" ? titleFn(pageContext) : titleFn;
87
- } catch (error) {
88
- console.error("+title hook failed at:", urlPathname);
89
- throw error;
90
- }
91
- return {
92
- pageContext,
93
- route,
94
- PageModule,
95
- HeadModule,
96
- LayoutModule
97
- };
98
- }
99
- async function renderErrorPage(req, status, urlPathname, error, nonce) {
100
- if (!store.errorRoute) return new Response(status === 404 ? "Not Found" : "Internal Server Error", { status });
101
- try {
102
- const { default: onRenderHtml } = await store.config.onRenderHtml();
103
- const [PageModule, HeadModule, LayoutModule] = await Promise.all([
104
- store.errorRoute.Page(),
105
- store.errorRoute.Head?.() ?? null,
106
- store.errorRoute.Layout?.() ?? null
107
- ]);
108
- const pageContext = {
109
- urlOriginal: req.url,
110
- urlPathname,
111
- routeParams: {},
112
- is404: status === 404,
113
- is500: status === 500,
114
- errorMessage: status === 500 && error instanceof Error ? error.message : void 0
115
- };
116
- const html = await onRenderHtml({
117
- pageContext,
118
- Page: PageModule.Page ?? PageModule.default,
119
- Layout: LayoutModule ? LayoutModule.Layout ?? LayoutModule.default : void 0,
120
- Head: HeadModule ? HeadModule.Head ?? HeadModule.default : void 0,
121
- pageTitleTag: `<title>${status === 404 ? "Page Not Found" : "Server Error"}</title>`,
122
- serializedContext: serializeContext(pageContext),
123
- assets: getAssets(store.errorRoute, nonce),
124
- nonce
125
- });
126
- return new Response(html, {
127
- status,
128
- headers: { "Content-Type": "text/html" }
129
- });
130
- } catch (renderError) {
131
- console.error("Error page render failed:", renderError);
132
- return new Response(status === 404 ? "Not Found" : "Internal Server Error", { status });
133
- }
134
- }
135
- async function renderPage(req, { nonce } = {}) {
136
- let { pathname } = new URL(req.url);
137
- if (BASE_URL !== "/") {
138
- const baseSlashed = BASE_URL.endsWith("/") ? BASE_URL : BASE_URL + "/";
139
- const baseNoSlash = baseSlashed.slice(0, -1);
140
- pathname = pathname === baseNoSlash ? "/" : pathname.slice(baseSlashed.length - 1);
141
- }
142
- const isJsonRequest = pathname.endsWith(".pageContext.json");
143
- let targetPathname = pathname;
144
- if (isJsonRequest) {
145
- targetPathname = targetPathname.replace(/\.pageContext\.json$/, "");
146
- if (targetPathname === "/index") targetPathname = "/";
147
- }
148
- try {
149
- const resolved = await buildPageContext(targetPathname, req.url, isJsonRequest);
150
- if (!resolved) {
151
- if (isJsonRequest) return Response.json({ is404: true }, { status: 404 });
152
- return renderErrorPage(req, 404, targetPathname, nonce);
153
- }
154
- const { pageContext, route, PageModule, HeadModule, LayoutModule } = resolved;
155
- if (isJsonRequest) return Response.json(pageContext);
156
- const { default: onRenderHtml } = await store.config.onRenderHtml();
157
- const html = await onRenderHtml({
158
- pageContext,
159
- Page: PageModule.Page ?? PageModule.default,
160
- Head: HeadModule ? HeadModule.Head ?? HeadModule.default : void 0,
161
- Layout: LayoutModule ? LayoutModule.Layout ?? LayoutModule.default : void 0,
162
- pageTitleTag: pageContext.title ? `<title>${pageContext.title}</title>` : "",
163
- serializedContext: serializeContext(pageContext),
164
- assets: getAssets(route, nonce),
165
- nonce
166
- });
167
- return new Response(html, {
168
- status: 200,
169
- headers: { "Content-Type": "text/html" }
170
- });
171
- } catch (error) {
172
- if (error instanceof AbortRedirect) {
173
- let redirectUrl = error.url;
174
- if (redirectUrl.startsWith("/")) redirectUrl = (BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL) + (redirectUrl === "/" ? "" : redirectUrl);
175
- if (isJsonRequest) return Response.json({ _redirect: redirectUrl }, { status: 200 });
176
- return new Response(null, {
177
- status: error.statusCode,
178
- headers: { Location: redirectUrl }
179
- });
180
- }
181
- if (error instanceof AbortRender) {
182
- if (isJsonRequest) return Response.json({
183
- is404: error.statusCode === 404,
184
- is500: error.statusCode >= 500,
185
- isError: true,
186
- reason: error.reason
187
- }, { status: error.statusCode });
188
- return renderErrorPage(req, error.statusCode, targetPathname, error.reason, nonce);
189
- }
190
- console.error("Render Error:", error);
191
- if (isJsonRequest) return Response.json({ is500: true }, { status: 500 });
192
- return renderErrorPage(req, 500, targetPathname, error, nonce);
193
- }
194
- }
195
- //#endregion
1
+ import { t as renderPage } from "./server-Cm1ZA_Dp.mjs";
196
2
  export { renderPage };
package/dist/vite.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { t as renderPage } from "./server-Cm1ZA_Dp.mjs";
1
2
  import fs from "node:fs";
2
3
  import path from "node:path";
3
4
  import { Readable } from "node:stream";
@@ -206,7 +207,7 @@ function routerPlugin({ pagesDir = "pages", serverEntry = "server/index", apiPre
206
207
  };
207
208
  },
208
209
  configResolved(config) {
209
- if (!config.plugins.some((plugin) => plugin.name?.startsWith("vike-lite-") && SUPPORTED_RENDERERS.includes(plugin.name.replace("vike-lite-", "")))) throw new Error(`No UI renderer plugin found in 'vite.config': please install and configure one of ${SUPPORTED_RENDERERS.map((r) => `vike-lite-${r}`).join(", ")}`);
210
+ if (!config.plugins.some((plugin) => plugin.name?.startsWith("vike-lite-") && SUPPORTED_RENDERERS.includes(plugin.name.replace("vike-lite-", "")))) throw new Error(`[vike-lite] No UI renderer plugin found in 'vite.config': please install and configure one of ${SUPPORTED_RENDERERS.map((r) => `vike-lite-${r}`).join(", ")}`);
210
211
  },
211
212
  resolveId(id) {
212
213
  if (VIRTUAL_VALUES.has(id)) return "\0" + id;
@@ -259,7 +260,7 @@ function routerPlugin({ pagesDir = "pages", serverEntry = "server/index", apiPre
259
260
  serverEntryPath = (basePath + ext).replaceAll("\\", "/");
260
261
  break;
261
262
  }
262
- if (!serverEntryPath) throw new Error(`[vike-lite] serverEntry ${serverEntry} file not found!`);
263
+ if (!serverEntryPath) throw new Error(`[vike-lite] serverEntry ${serverEntry} file not found`);
263
264
  return `import '${VIRTUAL.setup}';export * from'${serverEntryPath}';export{default}from'${serverEntryPath}';`;
264
265
  }
265
266
  return `import '${VIRTUAL.setup}';import{renderPage}from'vike-lite/server';
@@ -360,7 +361,6 @@ if (process.env.NODE_ENV === 'production') {
360
361
  if (!fs.existsSync(prerenderPath)) return;
361
362
  const { routes } = await import(pathToFileURL(prerenderPath).href);
362
363
  if (!routes) return;
363
- const { renderPage } = await import("vike-lite/server");
364
364
  const urlsToPrerender = /* @__PURE__ */ new Set();
365
365
  for (const route of routes) {
366
366
  let shouldPrerender = prerender;
@@ -386,29 +386,29 @@ if (process.env.NODE_ENV === 'production') {
386
386
  }
387
387
  }
388
388
  if (urlsToPrerender.size === 0) return;
389
- console.log("\n\x1B[36m📦 Starting Static Site Generation (SSG)...\x1B[0m");
389
+ console.log("[vike-lite] 📦 Starting Static Site Generation (SSG)");
390
390
  const { BASE_URL } = import.meta.env;
391
391
  const baseNoSlash = BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL;
392
392
  let generatedCount = 0;
393
393
  const clientDir = path.resolve(viteConfigRoot, outDir, "client");
394
394
  for (const urlPath of urlsToPrerender) {
395
395
  const htmlRes = await renderPage(new Request(`http://localhost${baseNoSlash}${urlPath}`));
396
- if (htmlRes && htmlRes.ok && htmlRes.headers.get("content-type")?.includes("text/html")) {
396
+ if (htmlRes?.ok && htmlRes.headers.get("content-type")?.includes("text/html")) {
397
397
  const outDirRoute = path.join(clientDir, urlPath === "/" ? "" : urlPath);
398
398
  fs.mkdirSync(outDirRoute, { recursive: true });
399
399
  fs.writeFileSync(path.join(outDirRoute, "index.html"), await htmlRes.text());
400
- } else throw new Error(`\u{1B}[31m✖ SSG HTML Error for ${urlPath}\u{1B}[0m`);
400
+ } else throw new Error(`[vike-lite] SSG HTML Error for "${urlPath}"`);
401
401
  const jsonTarget = urlPath === "/" ? "/index" : urlPath;
402
402
  const jsonRes = await renderPage(new Request(`http://localhost${baseNoSlash}${jsonTarget}.pageContext.json`));
403
- if (jsonRes && jsonRes.ok) {
403
+ if (jsonRes?.ok) {
404
404
  const jsonOutPath = path.join(clientDir, `${jsonTarget}.pageContext.json`);
405
405
  fs.mkdirSync(path.dirname(jsonOutPath), { recursive: true });
406
406
  fs.writeFileSync(jsonOutPath, await jsonRes.text());
407
- } else throw new Error(`\u{1B}[31m✖ SSG JSON Error for ${jsonTarget}\u{1B}[0m`);
408
- console.log(`\u{1B}[32m✓\u{1B}[0m Pre-rendered: ${urlPath}`);
407
+ } else throw new Error(`[vike-lite] SSG JSON Error for "${jsonTarget}"`);
408
+ console.log(` └─ ${urlPath}`);
409
409
  generatedCount++;
410
410
  }
411
- console.log(`\n\u{1B}[32m✨ SSG Completed! Generated ${generatedCount} static routes.\u{1B}[0m\n`);
411
+ console.log(`[vike-lite] ✨ SSG Completed! Generated ${generatedCount} static routes`);
412
412
  },
413
413
  configureServer(server) {
414
414
  return () => {
@@ -435,14 +435,14 @@ if (process.env.NODE_ENV === 'production') {
435
435
  headers
436
436
  };
437
437
  if (req.url.startsWith(apiPrefix)) {
438
- server.config.logger.info(`API request: ${req.method} ${req.url}`, { timestamp: true });
438
+ server.config.logger.info(`⚡ API: ${req.method} ${req.url}`, { timestamp: true });
439
439
  requestInit.body = Readable.toWeb(req);
440
440
  requestInit.duplex = "half";
441
- } else if (req.url.endsWith(".pageContext.json")) server.config.logger.info(`SPA Navigation request: ${req.url}`, { timestamp: true });
441
+ } else if (req.url.endsWith(".pageContext.json")) server.config.logger.info(`🔄 SPA Navigation: ${req.url}`, { timestamp: true });
442
442
  const response = await app.fetch(new Request(`http://${req.headers.host}${req.url}`, requestInit));
443
443
  res.statusCode = response.status;
444
444
  if (response.headers.get("content-type")?.includes("text/html")) {
445
- server.config.logger.info(`Page request: ${req.url}`, { timestamp: true });
445
+ server.config.logger.info(`📄 Page: ${req.url}`, { timestamp: true });
446
446
  let html = await response.text();
447
447
  html = await injectFOUCStyles(server, html);
448
448
  html = await server.transformIndexHtml(req.url, html);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike-lite",
3
- "version": "1.12.0",
3
+ "version": "1.13.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "module": "./dist/index.mjs",
@@ -46,11 +46,12 @@
46
46
  "dist"
47
47
  ],
48
48
  "scripts": {
49
+ "tsc": "tsc --noEmit",
49
50
  "build": "tsdown"
50
51
  },
51
52
  "devDependencies": {
52
53
  "@types/node": "^26.1.1",
53
- "tsdown": "^0.22.4",
54
+ "tsdown": "^0.22.5",
54
55
  "vite": "^8.1.4"
55
56
  },
56
57
  "peerDependencies": {
@@ -1,4 +0,0 @@
1
- //#region src/shared/index.ts
2
- const { BASE_URL } = import.meta.env;
3
- //#endregion
4
- export { BASE_URL as t };