vite-react-ssg 0.5.0 → 0.5.2

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
@@ -7,22 +7,24 @@ See demo(also document): [docs](https://vite-react-ssg.netlify.app/)
7
7
  [![NPM version](https://img.shields.io/npm/v/vite-react-ssg?color=a1b858&label=)](https://www.npmjs.com/package/vite-react-ssg)
8
8
 
9
9
  # Table of contents
10
- * [Usage](#usage)
11
- * [Extra route options](#extra-route-options)
12
- * [`entry`](#entry)
13
- * [`getStaticPaths`](#getstaticpaths)
14
- * [lazy](#lazy)
15
- * [`<ClientOnly/>`](#clientonly)
16
- * [Document head](#document-head)
17
- * [Reactive head](#reactive-head)
18
- * [CSS in JS](#css-in-js)
19
- * [Critical CSS](#critical-css)
20
- * [Configuration](#configuration)
21
- * [Custom Routes to Render](#custom-routes-to-render)
22
- * [Https](#https)
23
- * [Use CSR in development environment](#use-csr-in-development-environment)
24
- * [Roadmap](#roadmap)
25
- * [Credits](#credits)
10
+
11
+ - [Usage](#usage)
12
+ - [Extra route options](#extra-route-options)
13
+ - [`entry`](#entry)
14
+ - [`getStaticPaths`](#getstaticpaths)
15
+ - [lazy](#lazy)
16
+ - [`<ClientOnly/>`](#clientonly)
17
+ - [Document head](#document-head)
18
+ - [Reactive head](#reactive-head)
19
+ - [Public Base Path](#public-base-path)
20
+ - [CSS in JS](#css-in-js)
21
+ - [Critical CSS](#critical-css)
22
+ - [Configuration](#configuration)
23
+ - [Custom Routes to Render](#custom-routes-to-render)
24
+ - [Https](#https)
25
+ - [Use CSR in development environment](#use-csr-in-development-environment)
26
+ - [Roadmap](#roadmap)
27
+ - [Credits](#credits)
26
28
 
27
29
  ## Usage
28
30
 
@@ -34,10 +36,11 @@ See demo(also document): [docs](https://vite-react-ssg.netlify.app/)
34
36
  // package.json
35
37
  {
36
38
  "scripts": {
37
- - "dev": "vite",
38
39
  - "build": "vite build"
39
- + "dev": "vite-react-ssg dev",
40
40
  + "build": "vite-react-ssg build"
41
+ // If you need ssr when dev
42
+ - "dev": "vite",
43
+ + "dev": "vite-react-ssg dev",
41
44
 
42
45
  // OR if you want to use another vite config file
43
46
  + "build": "vite-react-ssg build -c another-vite.config.ts"
@@ -102,11 +105,13 @@ export const routes: RouteRecord[] = [
102
105
  The RouteObject of vite-react-ssg is based on react-router, and vite-react-ssg receives some additional properties.
103
106
 
104
107
  #### `entry`
108
+
105
109
  Used to obtain static resources.If you introduce static resources (such as css files) in that route and use lazy loading (such as React.lazy or route.lazy), you should set the entry field. It should be the path from root to the target file.
106
110
 
107
111
  eg: `src/pages/page1.tsx`
108
112
 
109
113
  #### `getStaticPaths`
114
+
110
115
  The `getStaticPaths()` function should return an array of path
111
116
  to determine which paths will be pre-rendered by vite-react-ssg.
112
117
 
@@ -123,6 +128,7 @@ const route = {
123
128
  ```
124
129
 
125
130
  ## lazy
131
+
126
132
  These options work well with the `lazy` field.
127
133
 
128
134
  ```tsx
@@ -139,6 +145,7 @@ export function getStaticPaths() {
139
145
 
140
146
  export const entry = 'src/pages/[page].tsx'
141
147
  ```
148
+
142
149
  ```ts
143
150
  // src/routes.ts
144
151
  const routes = [
@@ -179,14 +186,16 @@ You can use `<Head/>` to manage all of your changes to the document head. It tak
179
186
  ```tsx
180
187
  import { Head } from 'vite-react-ssg'
181
188
 
182
- const MyHead = () => (
183
- <Head>
184
- <meta property="og:description" content="My custom description" />
185
- <meta charSet="utf-8" />
186
- <title>My Title</title>
187
- <link rel="canonical" href="http://mysite.com/example" />
188
- </Head>
189
- )
189
+ function MyHead() {
190
+ return (
191
+ <Head>
192
+ <meta property="og:description" content="My custom description" />
193
+ <meta charSet="utf-8" />
194
+ <title>My Title</title>
195
+ <link rel="canonical" href="http://mysite.com/example" />
196
+ </Head>
197
+ )
198
+ }
190
199
  ```
191
200
 
192
201
  Nested or latter components will override duplicate usages:
@@ -194,23 +203,26 @@ Nested or latter components will override duplicate usages:
194
203
  ```tsx
195
204
  import { Head } from 'vite-react-ssg'
196
205
 
197
- const MyHead = () => (
198
- <parent>
199
- <Head>
200
- <title>My Title</title>
201
- <meta name="description" content="Helmet application" />
202
- </Head>
203
- <child>
206
+ function MyHead() {
207
+ return (
208
+ <parent>
204
209
  <Head>
205
- <title>Nested Title</title>
206
- <meta name="description" content="Nested component" />
210
+ <title>My Title</title>
211
+ <meta name="description" content="Helmet application" />
207
212
  </Head>
208
- </child>
209
- </parent>
210
- )
213
+ <child>
214
+ <Head>
215
+ <title>Nested Title</title>
216
+ <meta name="description" content="Nested component" />
217
+ </Head>
218
+ </child>
219
+ </parent>
220
+ )
221
+ }
211
222
  ```
212
223
 
213
224
  Outputs:
225
+
214
226
  ```html
215
227
  <head>
216
228
  <title>Nested Title</title>
@@ -239,6 +251,43 @@ export default function MyHead() {
239
251
  }
240
252
  ```
241
253
 
254
+ ## Public Base Path
255
+
256
+ Just set `base` in vite.config.ts like:
257
+
258
+ ```ts
259
+ // vite.config.ts
260
+ import { defineConfig } from 'vite'
261
+ import react from '@vitejs/plugin-react-swc'
262
+
263
+ // https://vitejs.dev/config/
264
+ export default defineConfig({
265
+ plugins: [react()],
266
+ base: '/base-path',
267
+ })
268
+ ```
269
+
270
+ ```ts
271
+ // main.ts
272
+ import { ViteReactSSG } from 'vite-react-ssg'
273
+ import { routes } from './App'
274
+ import './index.css'
275
+
276
+ export const createRoot = ViteReactSSG(
277
+ {
278
+ routes,
279
+ // pass your BASE_URL
280
+ basename: import.meta.env.BASE_URL,
281
+ },
282
+ )
283
+ ```
284
+
285
+ Vite React SSG will give it to the react-router's `basename`.
286
+
287
+ See: [react-router's create-browser-router](https://reactrouter.com/en/main/routers/create-browser-router#basename)
288
+
289
+ [Example](./examples/lazy-pages/vite.config.ts)
290
+
242
291
  ## CSS in JS
243
292
 
244
293
  Use the `getStyleCollector` option to specify an SSR/SSG style collector. Currently only supports `styled-components`.
@@ -252,14 +301,15 @@ import './index.css'
252
301
  export const createRoot = ViteReactSSG(
253
302
  { routes },
254
303
  () => { },
255
- { getStyleCollector: getStyledComponentsCollector })
304
+ { getStyleCollector: getStyledComponentsCollector }
305
+ )
256
306
  ```
257
307
 
258
308
  You can provide your own by looking at the [implementation](./src/style-collectors/) of any of the existing collectors.
259
309
 
260
310
  ## Critical CSS
261
311
 
262
- Vite SSG has built-in support for generating [Critical CSS](https://web.dev/extract-critical-css/) inlined in the HTML via the [`critters`](https://github.com/GoogleChromeLabs/critters) package.
312
+ Vite React SSG has built-in support for generating [Critical CSS](https://web.dev/extract-critical-css/) inlined in the HTML via the [`critters`](https://github.com/GoogleChromeLabs/critters) package.
263
313
  Install it with:
264
314
 
265
315
  ```bash
@@ -402,6 +452,7 @@ interface ViteReactSSGOptions {
402
452
  concurrency?: number
403
453
  }
404
454
  ```
455
+
405
456
  See [src/types.ts](./src/types.ts). for more options available.
406
457
 
407
458
  ### Custom Routes to Render
@@ -421,6 +472,7 @@ export default {
421
472
  },
422
473
  }
423
474
  ```
475
+
424
476
  ```js
425
477
  // vite.config.js
426
478
 
@@ -429,7 +481,7 @@ export default {
429
481
  ssgOptions: {
430
482
  includedRoutes(paths, routes) {
431
483
  // use original route records
432
- return routes.flatMap((route) => {
484
+ return routes.flatMap(route => {
433
485
  return route.name === 'Blog'
434
486
  ? myBlogSlugs.map(slug => `/blog/${slug}`)
435
487
  : route.path
@@ -454,6 +506,7 @@ export default defineConfig({
454
506
  ## Use CSR in development environment
455
507
 
456
508
  If you want to use CSR during development, just:
509
+
457
510
  ```ts
458
511
  // src/main.ts
459
512
  import { ViteReactSSG } from 'vite-react-ssg'
@@ -481,6 +534,7 @@ export const createRoot = ViteReactSSG(
481
534
  }
482
535
  }
483
536
  ```
537
+
484
538
  Then, you can start the application with CSR in the development environment.
485
539
 
486
540
  ## Roadmap
@@ -493,8 +547,9 @@ Then, you can start the application with CSR in the development environment.
493
547
  - [ ] Initial State
494
548
 
495
549
  ## Credits
550
+
496
551
  This project inspired by [vite-ssg](https://github.com/antfu/vite-ssg), thanks to [@antfu](https://github.com/antfu) for his awesome work.
497
552
 
498
553
  ## License
499
554
 
500
- [MIT](./LICENSE) License © 2023 [Riri](https://github.com/Daydreamer-riri)
555
+ [MIT](./LICENSE) License © 2023 [Riri](https://github.com/Daydreamer-riri)
package/dist/index.cjs CHANGED
@@ -72,6 +72,7 @@ const Link = React.forwardRef((props, ref) => {
72
72
  }
73
73
  return /* @__PURE__ */ React__default.createElement(reactRouterDom.Link, { ...props, ref, onClick: handleClick });
74
74
  });
75
+ Link.displayName = "Link";
75
76
  const NavLink = React.forwardRef((props, ref) => {
76
77
  const {
77
78
  replace,
@@ -102,6 +103,7 @@ const NavLink = React.forwardRef((props, ref) => {
102
103
  }
103
104
  return /* @__PURE__ */ React__default.createElement(reactRouterDom.NavLink, { ...props, ref, onClick: handleClick });
104
105
  });
106
+ NavLink.displayName = "NavLink";
105
107
 
106
108
  function ViteReactSSG(routerOptions, fn, options = {}) {
107
109
  const {
@@ -111,8 +113,9 @@ function ViteReactSSG(routerOptions, fn, options = {}) {
111
113
  getStyleCollector = null
112
114
  } = options;
113
115
  const isClient = typeof window !== "undefined";
116
+ const BASE_URL = routerOptions.basename ?? "/";
114
117
  async function createRoot(client = false, routePath) {
115
- const browserRouter = client ? reactRouterDom.createBrowserRouter(routerOptions.routes) : void 0;
118
+ const browserRouter = client ? reactRouterDom.createBrowserRouter(routerOptions.routes, { basename: BASE_URL }) : void 0;
116
119
  const appRenderCallbacks = [];
117
120
  const onSSRAppRendered = client ? () => {
118
121
  } : (cb) => appRenderCallbacks.push(cb);
@@ -129,6 +132,7 @@ function ViteReactSSG(routerOptions, fn, options = {}) {
129
132
  initialState: {},
130
133
  transformState,
131
134
  routePath,
135
+ base: BASE_URL,
132
136
  getStyleCollector
133
137
  };
134
138
  if (client) {
@@ -149,7 +153,7 @@ function ViteReactSSG(routerOptions, fn, options = {}) {
149
153
  if (isClient) {
150
154
  (async () => {
151
155
  const container = typeof rootContainer === "string" ? document.querySelector(rootContainer) : rootContainer;
152
- const lazeMatches = reactRouterDom.matchRoutes(routerOptions.routes, window.location)?.filter(
156
+ const lazeMatches = reactRouterDom.matchRoutes(routerOptions.routes, window.location, BASE_URL)?.filter(
153
157
  (m) => m.route.lazy
154
158
  );
155
159
  if (lazeMatches && lazeMatches?.length > 0) {
@@ -162,7 +166,7 @@ function ViteReactSSG(routerOptions, fn, options = {}) {
162
166
  }
163
167
  const { router } = await createRoot(true);
164
168
  const app = /* @__PURE__ */ React__default.createElement(reactHelmetAsync.HelmetProvider, null, /* @__PURE__ */ React__default.createElement(SiteMetadataDefaults.SiteMetadataDefaults, null), /* @__PURE__ */ React__default.createElement(reactRouterDom.RouterProvider, { router }));
165
- if (!ssrWhenDev && undefined.DEV) {
169
+ if (!ssrWhenDev && process.env.NODE_ENV === "development") {
166
170
  const root = client.createRoot(container);
167
171
  React__default.startTransition(() => {
168
172
  root.render(app);
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RouterOptions, a as ViteReactSSGContext, b as ViteReactSSGClientOptions } from './shared/vite-react-ssg.d5f23f74.cjs';
2
- export { I as IndexRouteRecord, N as NonIndexRouteRecord, c as RouteRecord, S as StyleCollector, V as ViteReactSSGOptions } from './shared/vite-react-ssg.d5f23f74.cjs';
1
+ import { R as RouterOptions, a as ViteReactSSGContext, b as ViteReactSSGClientOptions } from './shared/vite-react-ssg.4d8d5138.cjs';
2
+ export { I as IndexRouteRecord, N as NonIndexRouteRecord, c as RouteRecord, S as StyleCollector, V as ViteReactSSGOptions } from './shared/vite-react-ssg.4d8d5138.cjs';
3
3
  import React, { ReactNode } from 'react';
4
4
  import { HelmetProps } from 'react-helmet-async';
5
5
  import { LinkProps, NavLinkProps } from 'react-router-dom';
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RouterOptions, a as ViteReactSSGContext, b as ViteReactSSGClientOptions } from './shared/vite-react-ssg.d5f23f74.mjs';
2
- export { I as IndexRouteRecord, N as NonIndexRouteRecord, c as RouteRecord, S as StyleCollector, V as ViteReactSSGOptions } from './shared/vite-react-ssg.d5f23f74.mjs';
1
+ import { R as RouterOptions, a as ViteReactSSGContext, b as ViteReactSSGClientOptions } from './shared/vite-react-ssg.4d8d5138.mjs';
2
+ export { I as IndexRouteRecord, N as NonIndexRouteRecord, c as RouteRecord, S as StyleCollector, V as ViteReactSSGOptions } from './shared/vite-react-ssg.4d8d5138.mjs';
3
3
  import React, { ReactNode } from 'react';
4
4
  import { HelmetProps } from 'react-helmet-async';
5
5
  import { LinkProps, NavLinkProps } from 'react-router-dom';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RouterOptions, a as ViteReactSSGContext, b as ViteReactSSGClientOptions } from './shared/vite-react-ssg.d5f23f74.js';
2
- export { I as IndexRouteRecord, N as NonIndexRouteRecord, c as RouteRecord, S as StyleCollector, V as ViteReactSSGOptions } from './shared/vite-react-ssg.d5f23f74.js';
1
+ import { R as RouterOptions, a as ViteReactSSGContext, b as ViteReactSSGClientOptions } from './shared/vite-react-ssg.4d8d5138.js';
2
+ export { I as IndexRouteRecord, N as NonIndexRouteRecord, c as RouteRecord, S as StyleCollector, V as ViteReactSSGOptions } from './shared/vite-react-ssg.4d8d5138.js';
3
3
  import React, { ReactNode } from 'react';
4
4
  import { HelmetProps } from 'react-helmet-async';
5
5
  import { LinkProps, NavLinkProps } from 'react-router-dom';
package/dist/index.mjs CHANGED
@@ -67,6 +67,7 @@ const Link = forwardRef((props, ref) => {
67
67
  }
68
68
  return /* @__PURE__ */ React.createElement(Link$1, { ...props, ref, onClick: handleClick });
69
69
  });
70
+ Link.displayName = "Link";
70
71
  const NavLink = forwardRef((props, ref) => {
71
72
  const {
72
73
  replace,
@@ -97,6 +98,7 @@ const NavLink = forwardRef((props, ref) => {
97
98
  }
98
99
  return /* @__PURE__ */ React.createElement(NavLink$1, { ...props, ref, onClick: handleClick });
99
100
  });
101
+ NavLink.displayName = "NavLink";
100
102
 
101
103
  function ViteReactSSG(routerOptions, fn, options = {}) {
102
104
  const {
@@ -106,8 +108,9 @@ function ViteReactSSG(routerOptions, fn, options = {}) {
106
108
  getStyleCollector = null
107
109
  } = options;
108
110
  const isClient = typeof window !== "undefined";
111
+ const BASE_URL = routerOptions.basename ?? "/";
109
112
  async function createRoot$1(client = false, routePath) {
110
- const browserRouter = client ? createBrowserRouter(routerOptions.routes) : void 0;
113
+ const browserRouter = client ? createBrowserRouter(routerOptions.routes, { basename: BASE_URL }) : void 0;
111
114
  const appRenderCallbacks = [];
112
115
  const onSSRAppRendered = client ? () => {
113
116
  } : (cb) => appRenderCallbacks.push(cb);
@@ -124,6 +127,7 @@ function ViteReactSSG(routerOptions, fn, options = {}) {
124
127
  initialState: {},
125
128
  transformState,
126
129
  routePath,
130
+ base: BASE_URL,
127
131
  getStyleCollector
128
132
  };
129
133
  if (client) {
@@ -144,7 +148,7 @@ function ViteReactSSG(routerOptions, fn, options = {}) {
144
148
  if (isClient) {
145
149
  (async () => {
146
150
  const container = typeof rootContainer === "string" ? document.querySelector(rootContainer) : rootContainer;
147
- const lazeMatches = matchRoutes(routerOptions.routes, window.location)?.filter(
151
+ const lazeMatches = matchRoutes(routerOptions.routes, window.location, BASE_URL)?.filter(
148
152
  (m) => m.route.lazy
149
153
  );
150
154
  if (lazeMatches && lazeMatches?.length > 0) {
@@ -157,7 +161,7 @@ function ViteReactSSG(routerOptions, fn, options = {}) {
157
161
  }
158
162
  const { router } = await createRoot$1(true);
159
163
  const app = /* @__PURE__ */ React.createElement(HelmetProvider, null, /* @__PURE__ */ React.createElement(SiteMetadataDefaults, null), /* @__PURE__ */ React.createElement(RouterProvider, { router }));
160
- if (!ssrWhenDev && import.meta.env.DEV) {
164
+ if (!ssrWhenDev && process.env.NODE_ENV === "development") {
161
165
  const root = createRoot(container);
162
166
  React.startTransition(() => {
163
167
  root.render(app);
package/dist/node.cjs CHANGED
@@ -1066,8 +1066,8 @@ class WritableAsPromise extends node_stream.Writable {
1066
1066
  }
1067
1067
  }
1068
1068
 
1069
- async function render(routes, request, styleCollector) {
1070
- const { dataRoutes, query } = server_js.createStaticHandler(routes);
1069
+ async function render(routes, request, styleCollector, basename) {
1070
+ const { dataRoutes, query } = server_js.createStaticHandler(routes, { basename });
1071
1071
  const context = await query(request);
1072
1072
  const helmetContext = {};
1073
1073
  if (context instanceof Response)
@@ -1287,7 +1287,7 @@ async function build(ssgOptions = {}, viteConfig = {}) {
1287
1287
  const _require = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (document.currentScript && document.currentScript.src || new URL('node.cjs', document.baseURI).href)));
1288
1288
  const { createRoot, includedRoutes: serverEntryIncludedRoutes } = format === "esm" ? await import(serverEntry) : _require(serverEntry);
1289
1289
  const includedRoutes = serverEntryIncludedRoutes || configIncludedRoutes;
1290
- const { routes } = await createRoot(false);
1290
+ const { routes, base } = await createRoot(false);
1291
1291
  const { lazyPaths } = await routesToPaths(routes);
1292
1292
  const dataRoutes = await preLoad([...routes], lazyPaths);
1293
1293
  const { paths, pathToEntry } = await routesToPaths(dataRoutes);
@@ -1295,7 +1295,7 @@ async function build(ssgOptions = {}, viteConfig = {}) {
1295
1295
  routesPaths = DefaultIncludedRoutes(routesPaths);
1296
1296
  routesPaths = Array.from(new Set(routesPaths));
1297
1297
  buildLog("Rendering Pages...", routesPaths.length);
1298
- const critters = crittersOptions !== false ? await getCritters(outDir, crittersOptions) : void 0;
1298
+ const critters = crittersOptions !== false ? await getCritters(outDir, { publicPath: base, ...crittersOptions }) : void 0;
1299
1299
  if (critters)
1300
1300
  console.log(`${kolorist.gray("[vite-react-ssg]")} ${kolorist.blue("Critical CSS generation enabled via `critters`")}`);
1301
1301
  const dotVitedir = Number.parseInt(vite.version) >= 5 ? [".vite"] : [];
@@ -1309,11 +1309,12 @@ async function build(ssgOptions = {}, viteConfig = {}) {
1309
1309
  queue.add(async () => {
1310
1310
  try {
1311
1311
  const appCtx = await createRoot(false, path);
1312
- const { initialState, routes: routes2, triggerOnSSRAppRendered, transformState = SiteMetadataDefaults.serializeState, getStyleCollector } = appCtx;
1312
+ const { initialState, base: base2, routes: routes2, triggerOnSSRAppRendered, transformState = SiteMetadataDefaults.serializeState, getStyleCollector } = appCtx;
1313
1313
  const styleCollector = getStyleCollector ? await getStyleCollector() : null;
1314
1314
  const transformedIndexHTML = await onBeforePageRender?.(path, indexHTML, appCtx) || indexHTML;
1315
- const request = createRequest(path);
1316
- const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag } = await render([...routes2], request, styleCollector);
1315
+ const fetchUrl = `${base2.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
1316
+ const request = createRequest(fetchUrl);
1317
+ const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag } = await render([...routes2], request, styleCollector, base2);
1317
1318
  await triggerOnSSRAppRendered?.(path, appHTML, appCtx);
1318
1319
  const renderedHTML = await renderHTML({
1319
1320
  rootContainerId,
@@ -29029,6 +29030,7 @@ async function dev(ssgOptions = {}, viteConfig = {}) {
29029
29030
  const cwd = process.cwd();
29030
29031
  const root = config.root || cwd;
29031
29032
  const httpsOptions = config.server.https;
29033
+ setBase(config.rawBase);
29032
29034
  const {
29033
29035
  entry = await detectEntry(root),
29034
29036
  onBeforePageRender,
@@ -29063,17 +29065,19 @@ async function dev(ssgOptions = {}, viteConfig = {}) {
29063
29065
  server: { middlewareMode: true },
29064
29066
  appType: "custom"
29065
29067
  });
29066
- app.use(viteServer.middlewares);
29068
+ app.use((req, res, next) => {
29069
+ viteServer.middlewares.handle(req, res, next);
29070
+ });
29067
29071
  app.use("*", async (req, res) => {
29068
29072
  try {
29069
29073
  const url = req.originalUrl;
29070
29074
  const indexHTML = await viteServer.transformIndexHtml(url, template);
29071
29075
  const createRoot = await viteServer.ssrLoadModule(ssrEntry).then((m) => m.createRoot);
29072
29076
  const appCtx = await createRoot(false, url);
29073
- const { routes, getStyleCollector } = appCtx;
29077
+ const { routes, getStyleCollector, base: base2 } = appCtx;
29074
29078
  const transformedIndexHTML = await onBeforePageRender?.(url, indexHTML, appCtx) || indexHTML;
29075
29079
  const styleCollector = getStyleCollector ? await getStyleCollector() : null;
29076
- const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag, routerContext } = await render([...routes], createFetchRequest(req), styleCollector);
29080
+ const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag, routerContext } = await render([...routes], createFetchRequest(req), styleCollector, base2);
29077
29081
  metaAttributes.push(styleTag);
29078
29082
  const matchesEntries = routerContext.matches.map((match) => match.route.entry).filter((entry2) => !!entry2).map((entry2) => entry2[0] === "/" ? entry2 : `/${entry2}`);
29079
29083
  const mods = await Promise.all(
@@ -29121,7 +29125,7 @@ async function printServerInfo(server, onlyUrl = false, https2 = false) {
29121
29125
  const info = server.config.logger.info;
29122
29126
  const port = server.config.server.port || 5173;
29123
29127
  const protocol = https2 ? "https" : "http";
29124
- const url = `${protocol}://localhost:${port}/`;
29128
+ const url = `${protocol}://localhost:${port}/${getBase().replace(/^\//, "")}`;
29125
29129
  if (!onlyUrl) {
29126
29130
  let ssrReadyMessage = " -- SSR";
29127
29131
  if (globalThis.__ssr_start_time) {
@@ -29150,6 +29154,13 @@ function printUrls(url, info) {
29150
29154
  const colorUrl = (url2) => kolorist.cyan(url2.replace(/:(\d+)\//, (_, port) => `:${kolorist.bold(port)}/`));
29151
29155
  info(` ${kolorist.green("\u279C")} ${kolorist.bold("Local")}: ${colorUrl(url)}`);
29152
29156
  }
29157
+ let base = "";
29158
+ function getBase() {
29159
+ return base;
29160
+ }
29161
+ function setBase(newBase) {
29162
+ base = newBase;
29163
+ }
29153
29164
 
29154
29165
  exports.build = build;
29155
29166
  exports.dev = dev;
package/dist/node.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { InlineConfig } from 'vite';
2
- import { V as ViteReactSSGOptions } from './shared/vite-react-ssg.d5f23f74.cjs';
2
+ import { V as ViteReactSSGOptions } from './shared/vite-react-ssg.4d8d5138.cjs';
3
3
  import 'critters';
4
4
  import 'react';
5
5
  import 'react-router-dom';
package/dist/node.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { InlineConfig } from 'vite';
2
- import { V as ViteReactSSGOptions } from './shared/vite-react-ssg.d5f23f74.mjs';
2
+ import { V as ViteReactSSGOptions } from './shared/vite-react-ssg.4d8d5138.mjs';
3
3
  import 'critters';
4
4
  import 'react';
5
5
  import 'react-router-dom';
package/dist/node.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { InlineConfig } from 'vite';
2
- import { V as ViteReactSSGOptions } from './shared/vite-react-ssg.d5f23f74.js';
2
+ import { V as ViteReactSSGOptions } from './shared/vite-react-ssg.4d8d5138.js';
3
3
  import 'critters';
4
4
  import 'react';
5
5
  import 'react-router-dom';
package/dist/node.mjs CHANGED
@@ -1044,8 +1044,8 @@ class WritableAsPromise extends Writable {
1044
1044
  }
1045
1045
  }
1046
1046
 
1047
- async function render(routes, request, styleCollector) {
1048
- const { dataRoutes, query } = createStaticHandler(routes);
1047
+ async function render(routes, request, styleCollector, basename) {
1048
+ const { dataRoutes, query } = createStaticHandler(routes, { basename });
1049
1049
  const context = await query(request);
1050
1050
  const helmetContext = {};
1051
1051
  if (context instanceof Response)
@@ -1265,7 +1265,7 @@ async function build(ssgOptions = {}, viteConfig = {}) {
1265
1265
  const _require = createRequire(import.meta.url);
1266
1266
  const { createRoot, includedRoutes: serverEntryIncludedRoutes } = format === "esm" ? await import(serverEntry) : _require(serverEntry);
1267
1267
  const includedRoutes = serverEntryIncludedRoutes || configIncludedRoutes;
1268
- const { routes } = await createRoot(false);
1268
+ const { routes, base } = await createRoot(false);
1269
1269
  const { lazyPaths } = await routesToPaths(routes);
1270
1270
  const dataRoutes = await preLoad([...routes], lazyPaths);
1271
1271
  const { paths, pathToEntry } = await routesToPaths(dataRoutes);
@@ -1273,7 +1273,7 @@ async function build(ssgOptions = {}, viteConfig = {}) {
1273
1273
  routesPaths = DefaultIncludedRoutes(routesPaths);
1274
1274
  routesPaths = Array.from(new Set(routesPaths));
1275
1275
  buildLog("Rendering Pages...", routesPaths.length);
1276
- const critters = crittersOptions !== false ? await getCritters(outDir, crittersOptions) : void 0;
1276
+ const critters = crittersOptions !== false ? await getCritters(outDir, { publicPath: base, ...crittersOptions }) : void 0;
1277
1277
  if (critters)
1278
1278
  console.log(`${gray("[vite-react-ssg]")} ${blue("Critical CSS generation enabled via `critters`")}`);
1279
1279
  const dotVitedir = Number.parseInt(version$3) >= 5 ? [".vite"] : [];
@@ -1287,11 +1287,12 @@ async function build(ssgOptions = {}, viteConfig = {}) {
1287
1287
  queue.add(async () => {
1288
1288
  try {
1289
1289
  const appCtx = await createRoot(false, path);
1290
- const { initialState, routes: routes2, triggerOnSSRAppRendered, transformState = serializeState, getStyleCollector } = appCtx;
1290
+ const { initialState, base: base2, routes: routes2, triggerOnSSRAppRendered, transformState = serializeState, getStyleCollector } = appCtx;
1291
1291
  const styleCollector = getStyleCollector ? await getStyleCollector() : null;
1292
1292
  const transformedIndexHTML = await onBeforePageRender?.(path, indexHTML, appCtx) || indexHTML;
1293
- const request = createRequest(path);
1294
- const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag } = await render([...routes2], request, styleCollector);
1293
+ const fetchUrl = `${base2.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
1294
+ const request = createRequest(fetchUrl);
1295
+ const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag } = await render([...routes2], request, styleCollector, base2);
1295
1296
  await triggerOnSSRAppRendered?.(path, appHTML, appCtx);
1296
1297
  const renderedHTML = await renderHTML({
1297
1298
  rootContainerId,
@@ -29007,6 +29008,7 @@ async function dev(ssgOptions = {}, viteConfig = {}) {
29007
29008
  const cwd = process.cwd();
29008
29009
  const root = config.root || cwd;
29009
29010
  const httpsOptions = config.server.https;
29011
+ setBase(config.rawBase);
29010
29012
  const {
29011
29013
  entry = await detectEntry(root),
29012
29014
  onBeforePageRender,
@@ -29041,17 +29043,19 @@ async function dev(ssgOptions = {}, viteConfig = {}) {
29041
29043
  server: { middlewareMode: true },
29042
29044
  appType: "custom"
29043
29045
  });
29044
- app.use(viteServer.middlewares);
29046
+ app.use((req, res, next) => {
29047
+ viteServer.middlewares.handle(req, res, next);
29048
+ });
29045
29049
  app.use("*", async (req, res) => {
29046
29050
  try {
29047
29051
  const url = req.originalUrl;
29048
29052
  const indexHTML = await viteServer.transformIndexHtml(url, template);
29049
29053
  const createRoot = await viteServer.ssrLoadModule(ssrEntry).then((m) => m.createRoot);
29050
29054
  const appCtx = await createRoot(false, url);
29051
- const { routes, getStyleCollector } = appCtx;
29055
+ const { routes, getStyleCollector, base: base2 } = appCtx;
29052
29056
  const transformedIndexHTML = await onBeforePageRender?.(url, indexHTML, appCtx) || indexHTML;
29053
29057
  const styleCollector = getStyleCollector ? await getStyleCollector() : null;
29054
- const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag, routerContext } = await render([...routes], createFetchRequest(req), styleCollector);
29058
+ const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag, routerContext } = await render([...routes], createFetchRequest(req), styleCollector, base2);
29055
29059
  metaAttributes.push(styleTag);
29056
29060
  const matchesEntries = routerContext.matches.map((match) => match.route.entry).filter((entry2) => !!entry2).map((entry2) => entry2[0] === "/" ? entry2 : `/${entry2}`);
29057
29061
  const mods = await Promise.all(
@@ -29099,7 +29103,7 @@ async function printServerInfo(server, onlyUrl = false, https2 = false) {
29099
29103
  const info = server.config.logger.info;
29100
29104
  const port = server.config.server.port || 5173;
29101
29105
  const protocol = https2 ? "https" : "http";
29102
- const url = `${protocol}://localhost:${port}/`;
29106
+ const url = `${protocol}://localhost:${port}/${getBase().replace(/^\//, "")}`;
29103
29107
  if (!onlyUrl) {
29104
29108
  let ssrReadyMessage = " -- SSR";
29105
29109
  if (globalThis.__ssr_start_time) {
@@ -29128,5 +29132,12 @@ function printUrls(url, info) {
29128
29132
  const colorUrl = (url2) => cyan(url2.replace(/:(\d+)\//, (_, port) => `:${bold(port)}/`));
29129
29133
  info(` ${green("\u279C")} ${bold("Local")}: ${colorUrl(url)}`);
29130
29134
  }
29135
+ let base = "";
29136
+ function getBase() {
29137
+ return base;
29138
+ }
29139
+ function setBase(newBase) {
29140
+ base = newBase;
29141
+ }
29131
29142
 
29132
29143
  export { build, dev };
@@ -117,6 +117,7 @@ interface ViteReactSSGContext<HasRouter extends boolean = true> {
117
117
  * Current router path on SSG, `undefined` on client side.
118
118
  */
119
119
  routePath?: string;
120
+ base: string;
120
121
  getStyleCollector: (() => StyleCollector | Promise<StyleCollector>) | null;
121
122
  }
122
123
  interface ViteReactSSGClientOptions {
@@ -163,6 +164,7 @@ type RouteRecord = NonIndexRouteRecord | IndexRouteRecord;
163
164
  interface RouterOptions {
164
165
  routes: RouteRecord[];
165
166
  createFetchRequest?: <T>(req: T) => Request;
167
+ basename?: string;
166
168
  }
167
169
  interface StyleCollector {
168
170
  collect: (app: ReactElement) => ReactElement;
@@ -117,6 +117,7 @@ interface ViteReactSSGContext<HasRouter extends boolean = true> {
117
117
  * Current router path on SSG, `undefined` on client side.
118
118
  */
119
119
  routePath?: string;
120
+ base: string;
120
121
  getStyleCollector: (() => StyleCollector | Promise<StyleCollector>) | null;
121
122
  }
122
123
  interface ViteReactSSGClientOptions {
@@ -163,6 +164,7 @@ type RouteRecord = NonIndexRouteRecord | IndexRouteRecord;
163
164
  interface RouterOptions {
164
165
  routes: RouteRecord[];
165
166
  createFetchRequest?: <T>(req: T) => Request;
167
+ basename?: string;
166
168
  }
167
169
  interface StyleCollector {
168
170
  collect: (app: ReactElement) => ReactElement;
@@ -117,6 +117,7 @@ interface ViteReactSSGContext<HasRouter extends boolean = true> {
117
117
  * Current router path on SSG, `undefined` on client side.
118
118
  */
119
119
  routePath?: string;
120
+ base: string;
120
121
  getStyleCollector: (() => StyleCollector | Promise<StyleCollector>) | null;
121
122
  }
122
123
  interface ViteReactSSGClientOptions {
@@ -163,6 +164,7 @@ type RouteRecord = NonIndexRouteRecord | IndexRouteRecord;
163
164
  interface RouterOptions {
164
165
  routes: RouteRecord[];
165
166
  createFetchRequest?: <T>(req: T) => Request;
167
+ basename?: string;
166
168
  }
167
169
  interface StyleCollector {
168
170
  collect: (app: ReactElement) => ReactElement;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vite-react-ssg",
3
3
  "type": "module",
4
- "version": "0.5.0",
4
+ "version": "0.5.2",
5
5
  "packageManager": "pnpm@8.6.6",
6
6
  "description": "",
7
7
  "author": "Riri <Daydreamerriri@outlook.com>",
@@ -54,9 +54,9 @@
54
54
  "vite-react-ssg": "bin/vite-react-ssg.js"
55
55
  },
56
56
  "files": [
57
- "dist",
57
+ "*.d.ts",
58
58
  "bin",
59
- "*.d.ts"
59
+ "dist"
60
60
  ],
61
61
  "scripts": {
62
62
  "build": "unbuild",
@@ -101,7 +101,7 @@
101
101
  },
102
102
  "devDependencies": {
103
103
  "@childrentime/devcert": "^1.2.5",
104
- "@ririd/eslint-config": "0.7.0",
104
+ "@ririd/eslint-config": "^1.0.0",
105
105
  "@types/express": "^4.17.17",
106
106
  "@types/fs-extra": "^11.0.1",
107
107
  "@types/html-minifier": "^4.0.2",
@@ -112,7 +112,7 @@
112
112
  "@types/yargs": "^17.0.24",
113
113
  "bumpp": "^9.1.0",
114
114
  "critters": "^0.0.20",
115
- "eslint": "^8.45.0",
115
+ "eslint": "^8.56.0",
116
116
  "esno": "^4.0.0",
117
117
  "fast-glob": "3.3.1",
118
118
  "p-queue": "^8.0.0",