@inertiajs/vite 3.0.0-beta.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.
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Jonathan Reinink <jonathan@reinink.ca>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.js ADDED
@@ -0,0 +1,634 @@
1
+ // src/index.ts
2
+ import { existsSync as existsSync2 } from "node:fs";
3
+ import { resolve as resolve3 } from "node:path";
4
+
5
+ // src/frameworks/react.ts
6
+ var config = {
7
+ // Package name used to detect React usage via import statements
8
+ package: "@inertiajs/react",
9
+ // React components can use either .tsx (TypeScript) or .jsx
10
+ // The plugin tries .tsx first, then falls back to .jsx
11
+ extensions: [".tsx", ".jsx"],
12
+ // React components are exported as `export default`, so we need to extract .default
13
+ extractDefault: true,
14
+ // SSR template that wraps the createInertiaApp call with server bootstrap code
15
+ // Uses import.meta.env.PROD to skip the standalone server in dev mode
16
+ ssr: (configureCall, options) => `
17
+ import createServer from '@inertiajs/react/server'
18
+ import { renderToString } from 'react-dom/server'
19
+
20
+ const render = await ${configureCall}
21
+
22
+ const renderPage = (page) => render(page, renderToString)
23
+
24
+ if (import.meta.env.PROD) {
25
+ createServer(renderPage${options})
26
+ }
27
+
28
+ export default renderPage
29
+ `
30
+ };
31
+
32
+ // src/frameworks/svelte.ts
33
+ var config2 = {
34
+ // Package name used to detect Svelte usage via import statements
35
+ package: "@inertiajs/svelte",
36
+ // Svelte components use .svelte extension
37
+ extensions: [".svelte"],
38
+ // Svelte components ARE the module - no .default extraction needed
39
+ // This is different from Vue/React where components use `export default`
40
+ extractDefault: false,
41
+ // SSR template that wraps the createInertiaApp call with server bootstrap code
42
+ // Uses import.meta.env.PROD to skip the standalone server in dev mode
43
+ // Note: Svelte uses a different variable name (ssr) and render function import
44
+ ssr: (configureCall, options) => `
45
+ import createServer from '@inertiajs/svelte/server'
46
+ import { render } from 'svelte/server'
47
+
48
+ const ssr = await ${configureCall}
49
+
50
+ const renderPage = (page) => ssr(page, render)
51
+
52
+ if (import.meta.env.PROD) {
53
+ createServer(renderPage${options})
54
+ }
55
+
56
+ export default renderPage
57
+ `
58
+ };
59
+
60
+ // src/frameworks/vue.ts
61
+ var config3 = {
62
+ // Package name used to detect Vue usage via import statements
63
+ package: "@inertiajs/vue3",
64
+ // Vue single-file components use .vue extension
65
+ extensions: [".vue"],
66
+ // Vue components are exported as `export default`, so we need to extract .default
67
+ extractDefault: true,
68
+ // SSR template that wraps the createInertiaApp call with server bootstrap code
69
+ // Uses import.meta.env.PROD to skip the standalone server in dev mode
70
+ ssr: (configureCall, options) => `
71
+ import createServer from '@inertiajs/vue3/server'
72
+ import { renderToString } from 'vue/server-renderer'
73
+
74
+ const render = await ${configureCall}
75
+
76
+ const renderPage = (page) => render(page, renderToString)
77
+
78
+ if (import.meta.env.PROD) {
79
+ createServer(renderPage${options})
80
+ }
81
+
82
+ export default renderPage
83
+ `
84
+ };
85
+
86
+ // src/frameworks/index.ts
87
+ var frameworks = [config3, config, config2];
88
+ var defaultFrameworks = Object.fromEntries(
89
+ frameworks.map((config4) => [config4.package, config4])
90
+ );
91
+
92
+ // src/astUtils.ts
93
+ import { parseAst } from "vite";
94
+ var INERTIA_APP_FUNCTION = "createInertiaApp";
95
+ var CREATE_SERVER_FUNCTION = "createServer";
96
+ var ParsedCode = class _ParsedCode {
97
+ constructor(ast) {
98
+ this.ast = ast;
99
+ }
100
+ /** Returns null if parsing fails (e.g. non-JS file content). */
101
+ static from(code) {
102
+ try {
103
+ return new _ParsedCode(parseAst(code));
104
+ } catch {
105
+ return null;
106
+ }
107
+ }
108
+ get importSources() {
109
+ const sources = [];
110
+ for (const node of this.ast.body) {
111
+ if (node.type === "ImportDeclaration") {
112
+ sources.push(node.source.value);
113
+ }
114
+ }
115
+ return sources;
116
+ }
117
+ detectFramework(frameworks2) {
118
+ const name = this.importSources.find((source) => source in frameworks2);
119
+ return name ? { name, config: frameworks2[name] } : null;
120
+ }
121
+ /**
122
+ * Find a top-level `createInertiaApp()` expression statement.
123
+ * Only matches bare calls, not `export default createInertiaApp()`.
124
+ */
125
+ get inertiaStatement() {
126
+ for (const node of this.ast.body) {
127
+ if (node.type !== "ExpressionStatement") {
128
+ continue;
129
+ }
130
+ const statement = node;
131
+ let expr = statement.expression;
132
+ if (expr.type === "AwaitExpression") {
133
+ expr = expr.argument;
134
+ }
135
+ if (expr.type === "CallExpression") {
136
+ const call = expr;
137
+ if (this.isInertiaCall(call)) {
138
+ return { statement, call };
139
+ }
140
+ }
141
+ }
142
+ return null;
143
+ }
144
+ /** Find a top-level `createServer()` call (not nested in exports). */
145
+ get createServerStatement() {
146
+ for (const node of this.ast.body) {
147
+ if (node.type !== "ExpressionStatement") {
148
+ continue;
149
+ }
150
+ const statement = node;
151
+ const expr = statement.expression;
152
+ if (expr.type === "CallExpression") {
153
+ const call = expr;
154
+ if (call.callee.type === "Identifier" && call.callee.name === CREATE_SERVER_FUNCTION) {
155
+ return statement;
156
+ }
157
+ }
158
+ }
159
+ return null;
160
+ }
161
+ /**
162
+ * Find all `createInertiaApp()` calls, including those nested inside exports.
163
+ */
164
+ get inertiaCalls() {
165
+ const calls = [];
166
+ this.walkAst(this.ast, (node) => {
167
+ if (node.type === "CallExpression" && this.isInertiaCall(node)) {
168
+ calls.push(node);
169
+ }
170
+ });
171
+ return calls;
172
+ }
173
+ get pagesProperty() {
174
+ for (const call of this.inertiaCalls) {
175
+ if (call.arguments.length === 0 || call.arguments[0].type !== "ObjectExpression") {
176
+ continue;
177
+ }
178
+ for (const prop of call.arguments[0].properties) {
179
+ if (prop.type !== "Property" || prop.key.type !== "Identifier" || prop.key.name !== "pages") {
180
+ continue;
181
+ }
182
+ return prop;
183
+ }
184
+ }
185
+ return null;
186
+ }
187
+ /** Find a `createInertiaApp()` call that has no `pages` or `resolve` property yet. */
188
+ get callWithoutResolver() {
189
+ for (const call of this.inertiaCalls) {
190
+ const callWithPos = call;
191
+ if (call.arguments.length === 0) {
192
+ return { callEnd: callWithPos.end };
193
+ }
194
+ if (call.arguments[0].type !== "ObjectExpression") {
195
+ continue;
196
+ }
197
+ const obj = call.arguments[0];
198
+ const hasResolver = obj.properties.some(
199
+ (p) => p.type === "Property" && p.key.type === "Identifier" && (p.key.name === "pages" || p.key.name === "resolve")
200
+ );
201
+ if (hasResolver) {
202
+ continue;
203
+ }
204
+ return {
205
+ callEnd: callWithPos.end,
206
+ options: { start: obj.start, end: obj.end, isEmpty: obj.properties.length === 0 }
207
+ };
208
+ }
209
+ return null;
210
+ }
211
+ isInertiaCall(node) {
212
+ return node.callee.type === "Identifier" && node.callee.name === INERTIA_APP_FUNCTION;
213
+ }
214
+ walkAst(node, callback) {
215
+ if (!node || typeof node !== "object") {
216
+ return;
217
+ }
218
+ if ("type" in node) {
219
+ callback(node);
220
+ }
221
+ for (const value of Object.values(node)) {
222
+ if (Array.isArray(value)) {
223
+ for (const item of value) {
224
+ this.walkAst(item, callback);
225
+ }
226
+ } else {
227
+ this.walkAst(value, callback);
228
+ }
229
+ }
230
+ }
231
+ };
232
+ function extractString(node) {
233
+ if (node.type === "Literal" && typeof node.value === "string") {
234
+ return node.value;
235
+ }
236
+ if (node.type === "TemplateLiteral" && node.expressions.length === 0) {
237
+ return node.quasis[0].value.cooked ?? node.quasis[0].value.raw;
238
+ }
239
+ return void 0;
240
+ }
241
+ function extractStringArray(node) {
242
+ if (node.type !== "ArrayExpression") {
243
+ return void 0;
244
+ }
245
+ const strings = node.elements.map((el) => el ? extractString(el) : void 0).filter((s) => s !== void 0);
246
+ return strings.length > 0 ? strings : void 0;
247
+ }
248
+ function extractBoolean(node) {
249
+ if (node.type === "Literal" && typeof node.value === "boolean") {
250
+ return node.value;
251
+ }
252
+ return void 0;
253
+ }
254
+
255
+ // src/pagesTransform.ts
256
+ function transformPageResolution(code, frameworks2) {
257
+ if (!code.includes("InertiaApp")) {
258
+ return null;
259
+ }
260
+ const parsed = ParsedCode.from(code);
261
+ if (!parsed) {
262
+ return null;
263
+ }
264
+ const framework = parsed.detectFramework(frameworks2);
265
+ if (!framework) {
266
+ return null;
267
+ }
268
+ const extensions = framework.config.extensions;
269
+ const extractDefault = framework.config.extractDefault ?? true;
270
+ if (parsed.pagesProperty) {
271
+ return replacePages(code, parsed.pagesProperty, extensions, extractDefault);
272
+ }
273
+ if (parsed.callWithoutResolver) {
274
+ return injectResolver(code, parsed.callWithoutResolver, extensions, extractDefault);
275
+ }
276
+ return null;
277
+ }
278
+ function replacePages(code, property, defaultExtensions, extractDefault) {
279
+ const config4 = extractPagesConfig(property.value, code);
280
+ if (!config4) {
281
+ return code;
282
+ }
283
+ const extensions = config4.extensions ? Array.isArray(config4.extensions) ? config4.extensions : [config4.extensions] : defaultExtensions;
284
+ const eager = !(config4.lazy ?? true);
285
+ const resolver = config4.directory ? buildResolver(config4.directory.replace(/\/$/, ""), extensions, extractDefault, eager, config4.transform) : buildDefaultResolver(extensions, extractDefault, eager);
286
+ return code.slice(0, property.start) + resolver + code.slice(property.end);
287
+ }
288
+ function injectResolver(code, call, extensions, extractDefault) {
289
+ const resolver = buildDefaultResolver(extensions, extractDefault);
290
+ if (!call.options) {
291
+ return code.slice(0, call.callEnd - 1) + `{ ${resolver} })` + code.slice(call.callEnd);
292
+ }
293
+ if (call.options.isEmpty) {
294
+ return code.slice(0, call.options.start) + `{ ${resolver} }` + code.slice(call.options.end);
295
+ }
296
+ return code.slice(0, call.options.start + 1) + ` ${resolver},` + code.slice(call.options.start + 1);
297
+ }
298
+ function extractPagesConfig(node, code) {
299
+ const str = extractString(node);
300
+ if (str) {
301
+ return { directory: str };
302
+ }
303
+ if (node.type !== "ObjectExpression") {
304
+ return null;
305
+ }
306
+ let directory;
307
+ let extensions;
308
+ let transform;
309
+ let lazy;
310
+ for (const prop of node.properties) {
311
+ if (prop.type !== "Property" || prop.key.type !== "Identifier") {
312
+ continue;
313
+ }
314
+ const key = prop.key.name;
315
+ const value = prop.value;
316
+ if (key === "path") {
317
+ directory = extractString(value);
318
+ } else if (key === "extension") {
319
+ extensions = extractString(value) ?? extractStringArray(value);
320
+ } else if (key === "transform") {
321
+ transform = code.slice(value.start, value.end);
322
+ } else if (key === "lazy") {
323
+ lazy = extractBoolean(value);
324
+ }
325
+ }
326
+ return { directory, extensions, transform, lazy };
327
+ }
328
+ function buildResolver(directories, extensions, extractDefault, eager, transform) {
329
+ const dirs = Array.isArray(directories) ? directories : [directories];
330
+ const globs = dirs.map((d) => buildGlob(d, extensions));
331
+ const glob = globs.length === 1 ? `'${globs[0]}'` : `['${globs.join("', '")}']`;
332
+ const nameVar = transform ? "resolvedName" : "name";
333
+ const lookup = dirs.flatMap((d) => extensions.map((ext) => `pages[\`${d}/\${${nameVar}}${ext}\`]`)).join(" || ");
334
+ const transformLine = transform ? `const resolvedName = (${transform})(name, page)
335
+ ` : "";
336
+ const returnValue = extractDefault ? "module.default ?? module" : "module";
337
+ const globOptions = `, { eager: ${eager} }`;
338
+ const moduleLookup = eager ? lookup : `await (${lookup})?.()`;
339
+ return `resolve: async (name, page) => {
340
+ ${transformLine}const pages = import.meta.glob(${glob}${globOptions})
341
+ const module = ${moduleLookup}
342
+ if (!module) throw new Error(\`Page not found: \${name}\`)
343
+ return ${returnValue}
344
+ }`;
345
+ }
346
+ function buildDefaultResolver(extensions, extractDefault, eager = false) {
347
+ return buildResolver(["./pages", "./Pages"], extensions, extractDefault, eager);
348
+ }
349
+ function buildGlob(directory, extensions) {
350
+ const ext = extensions.length === 1 ? extensions[0] : `{${extensions.join(",")}}`;
351
+ return `${directory}/**/*${ext}`;
352
+ }
353
+
354
+ // src/ssr.ts
355
+ import { classifySSRError, formatConsoleError } from "@inertiajs/core/ssrErrors";
356
+ import { existsSync } from "node:fs";
357
+ import { resolve as resolve2 } from "node:path";
358
+
359
+ // src/css.ts
360
+ import { resolve } from "node:path";
361
+ function collectCSSFromModuleGraph(server, entry) {
362
+ const entryModule = resolveEntryModule(server, entry);
363
+ if (!entryModule) {
364
+ return [];
365
+ }
366
+ const cssModules = collectCSSModules(entryModule);
367
+ if (cssModules.length === 0) {
368
+ return [];
369
+ }
370
+ const origin = resolveDevServerOrigin(server);
371
+ const base = server.config.base || "/";
372
+ const basePrefix = base === "/" ? "" : base;
373
+ return cssModules.map(({ url, id }) => {
374
+ const href = `${origin}${basePrefix}${url}`;
375
+ const devId = id ? ` data-vite-dev-id="${id}"` : "";
376
+ return `<link rel="stylesheet" href="${href}"${devId}>`;
377
+ });
378
+ }
379
+ function resolveEntryModule(server, entry) {
380
+ const resolvedEntry = resolve(server.config.root, entry);
381
+ return server.environments.ssr.moduleGraph.getModuleById(resolvedEntry);
382
+ }
383
+ function collectCSSModules(entryModule) {
384
+ const cssModules = [];
385
+ const visited = /* @__PURE__ */ new Set();
386
+ function traverse(mod) {
387
+ if (visited.has(mod)) {
388
+ return;
389
+ }
390
+ visited.add(mod);
391
+ if (isCSSRequest(mod.url)) {
392
+ cssModules.push({ url: mod.url, id: mod.id });
393
+ }
394
+ for (const imported of mod.importedModules) {
395
+ traverse(imported);
396
+ }
397
+ }
398
+ traverse(entryModule);
399
+ return cssModules;
400
+ }
401
+ var CSS_EXTENSIONS = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
402
+ function isCSSRequest(url) {
403
+ return CSS_EXTENSIONS.test(url);
404
+ }
405
+ function resolveDevServerOrigin(server) {
406
+ if (server.resolvedUrls?.local[0]) {
407
+ return server.resolvedUrls.local[0].replace(/\/$/, "");
408
+ }
409
+ const protocol = server.config.server.https ? "https" : "http";
410
+ const port = server.config.server.port ?? 5173;
411
+ return `${protocol}://localhost:${port}`;
412
+ }
413
+
414
+ // src/ssr.ts
415
+ var SSR_ENDPOINT = "/__inertia_ssr";
416
+ var SSR_ENTRY_CANDIDATES = [
417
+ "resources/js/ssr.ts",
418
+ "resources/js/ssr.tsx",
419
+ "resources/js/ssr.js",
420
+ "resources/js/ssr.jsx",
421
+ "src/ssr.ts",
422
+ "src/ssr.tsx",
423
+ "src/ssr.js",
424
+ "src/ssr.jsx",
425
+ "resources/js/app.ts",
426
+ "resources/js/app.tsx",
427
+ "resources/js/app.js",
428
+ "resources/js/app.jsx",
429
+ "src/app.ts",
430
+ "src/app.tsx",
431
+ "src/app.js",
432
+ "src/app.jsx"
433
+ ];
434
+ function resolveSSREntry(options, config4) {
435
+ if (options.entry) {
436
+ if (existsSync(resolve2(config4.root, options.entry))) {
437
+ return options.entry;
438
+ }
439
+ config4.logger.warn(`Inertia SSR entry not found: ${options.entry}`);
440
+ return null;
441
+ }
442
+ return SSR_ENTRY_CANDIDATES.find((path) => existsSync(resolve2(config4.root, path))) ?? null;
443
+ }
444
+ async function handleSSRRequest(server, entry, req, res, handleErrors = true) {
445
+ let component;
446
+ let url;
447
+ const originalWarn = console.warn;
448
+ const suppressedWarnings = [];
449
+ console.warn = (...args) => {
450
+ const message = args[0]?.toString() ?? "";
451
+ if (message.includes("[Vue warn]") || message.includes("at <")) {
452
+ if (handleErrors) {
453
+ suppressedWarnings.push(args.map(String).join(" "));
454
+ }
455
+ return;
456
+ }
457
+ originalWarn.apply(console, args);
458
+ };
459
+ try {
460
+ const page = await readRequestBody(req);
461
+ component = page.component;
462
+ url = page.url;
463
+ const start = performance.now();
464
+ const render = await loadRenderFunction(server, entry);
465
+ const result = await render(page);
466
+ if (!result || typeof result.body !== "string") {
467
+ throw new Error(`SSR render must return { head: string[], body: string }`);
468
+ }
469
+ const cssLinks = collectCSSFromModuleGraph(server, entry);
470
+ result.head = [...cssLinks, ...result.head];
471
+ logSSRRequest(server, page.component, start);
472
+ res.setHeader("Content-Type", "application/json");
473
+ res.end(JSON.stringify(result));
474
+ } catch (error) {
475
+ handleSSRError(server, res, error, component, url, handleErrors, suppressedWarnings);
476
+ } finally {
477
+ console.warn = originalWarn;
478
+ }
479
+ }
480
+ async function loadRenderFunction(server, entry) {
481
+ const module = await server.ssrLoadModule(entry);
482
+ const render = await Promise.resolve(module.default);
483
+ if (typeof render !== "function") {
484
+ throw new Error(`SSR entry "${entry}" must export a render function`);
485
+ }
486
+ return render;
487
+ }
488
+ function readRequestBody(req) {
489
+ return new Promise((resolve4, reject) => {
490
+ let data = "";
491
+ req.on("data", (chunk) => data += chunk);
492
+ req.on("end", () => {
493
+ if (!data.trim()) {
494
+ reject(new Error("Request body is empty"));
495
+ return;
496
+ }
497
+ try {
498
+ resolve4(JSON.parse(data));
499
+ } catch (error) {
500
+ reject(new Error(`Invalid JSON in request body: ${error instanceof Error ? error.message : "Unknown error"}`));
501
+ }
502
+ });
503
+ req.on("error", reject);
504
+ });
505
+ }
506
+ function logSSRRequest(server, component, start) {
507
+ const duration = (performance.now() - start).toFixed(2);
508
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
509
+ server.config.logger.info(`\x1B[32m${timestamp}\x1B[0m SSR ${component} \x1B[90m${duration}ms\x1B[0m`);
510
+ }
511
+ function handleSSRError(server, res, error, component, url, handleErrors = true, suppressedWarnings = []) {
512
+ server.ssrFixStacktrace(error);
513
+ if (!handleErrors) {
514
+ throw error;
515
+ }
516
+ const classified = classifySSRError(error, component, url);
517
+ server.config.logger.error(formatConsoleError(classified, server.config.root, handleErrors, suppressedWarnings));
518
+ res.setHeader("Content-Type", "application/json");
519
+ res.statusCode = 500;
520
+ res.end(JSON.stringify(classified));
521
+ }
522
+
523
+ // src/ssrTransform.ts
524
+ function formatSSROptions(options) {
525
+ const entries = Object.entries(options).filter(([, v]) => v !== void 0);
526
+ return entries.length > 0 ? `, ${JSON.stringify(Object.fromEntries(entries))}` : "";
527
+ }
528
+ function findInertiaAppExport(code) {
529
+ const parsed = ParsedCode.from(code);
530
+ return !!(parsed?.inertiaStatement || parsed?.createServerStatement);
531
+ }
532
+ function wrapWithServerBootstrap(code, options, frameworks2) {
533
+ const parsed = ParsedCode.from(code);
534
+ if (!parsed) {
535
+ return null;
536
+ }
537
+ if (parsed.inertiaStatement) {
538
+ const framework = parsed.detectFramework(frameworks2);
539
+ if (!framework?.config.ssr) {
540
+ return null;
541
+ }
542
+ const { statement, call } = parsed.inertiaStatement;
543
+ const configureCall = code.slice(call.start, call.end);
544
+ const ssrCode = framework.config.ssr(configureCall, formatSSROptions(options)).trim();
545
+ return code.slice(0, statement.start) + ssrCode + code.slice(statement.end);
546
+ }
547
+ if (parsed.createServerStatement) {
548
+ const statement = parsed.createServerStatement;
549
+ const args = statement.expression.arguments;
550
+ const callback = code.slice(args[0].start, args[0].end);
551
+ const trailingArgs = code.slice(args[0].end, args[args.length - 1].end);
552
+ const replacement = `const renderPage = ${callback}
553
+
554
+ if (import.meta.env.PROD) {
555
+ createServer(renderPage${trailingArgs})
556
+ }
557
+
558
+ export default renderPage`;
559
+ return code.slice(0, statement.start) + replacement + code.slice(statement.end);
560
+ }
561
+ return null;
562
+ }
563
+
564
+ // src/index.ts
565
+ function toFrameworkRecord(input) {
566
+ if (!input) {
567
+ return {};
568
+ }
569
+ const configs = Array.isArray(input) ? input : [input];
570
+ return Object.fromEntries(configs.map((config4) => [config4.package, config4]));
571
+ }
572
+ function inertia(options = {}) {
573
+ const ssrDisabled = options.ssr === false;
574
+ const ssr = typeof options.ssr === "string" ? { entry: options.ssr } : options.ssr || {};
575
+ const frameworks2 = { ...defaultFrameworks, ...toFrameworkRecord(options.frameworks) };
576
+ let entry = null;
577
+ return {
578
+ name: "@inertiajs/vite",
579
+ config(config4, env) {
580
+ if (ssrDisabled || !env.isSsrBuild) {
581
+ return;
582
+ }
583
+ const root = config4.root ?? process.cwd();
584
+ const ssrEntry = ssr.entry ?? SSR_ENTRY_CANDIDATES.find((candidate) => existsSync2(resolve3(root, candidate)));
585
+ return {
586
+ build: {
587
+ sourcemap: ssr.sourcemap !== false ? config4.build?.sourcemap ?? true : void 0,
588
+ rollupOptions: ssrEntry ? {
589
+ input: config4.build?.rollupOptions?.input ?? ssrEntry
590
+ } : void 0
591
+ }
592
+ };
593
+ },
594
+ configResolved(config4) {
595
+ if (ssrDisabled) {
596
+ return;
597
+ }
598
+ entry = resolveSSREntry(ssr, config4);
599
+ if (entry && config4.build?.ssr) {
600
+ config4.logger.info(`Inertia SSR entry: ${entry}`);
601
+ }
602
+ },
603
+ transform(code, id, options2) {
604
+ if (!/\.[jt]sx?$/.test(id)) {
605
+ return null;
606
+ }
607
+ let result = code;
608
+ if (!ssrDisabled && options2?.ssr && findInertiaAppExport(result)) {
609
+ result = wrapWithServerBootstrap(
610
+ result,
611
+ { port: ssr.port, cluster: ssr.cluster, handleErrors: ssr.handleErrors },
612
+ frameworks2
613
+ ) ?? result;
614
+ }
615
+ return transformPageResolution(result, frameworks2) ?? (result !== code ? result : null);
616
+ },
617
+ configureServer(server) {
618
+ if (!entry) {
619
+ return;
620
+ }
621
+ server.middlewares.use(SSR_ENDPOINT, async (req, res, next) => {
622
+ if (req.method !== "POST") {
623
+ return next();
624
+ }
625
+ await handleSSRRequest(server, entry, req, res, ssr.handleErrors ?? true);
626
+ });
627
+ server.config.logger.info(`Inertia SSR dev endpoint: ${SSR_ENDPOINT}`);
628
+ }
629
+ };
630
+ }
631
+ export {
632
+ inertia as default
633
+ };
634
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts", "../src/frameworks/react.ts", "../src/frameworks/svelte.ts", "../src/frameworks/vue.ts", "../src/frameworks/index.ts", "../src/astUtils.ts", "../src/pagesTransform.ts", "../src/ssr.ts", "../src/css.ts", "../src/ssrTransform.ts"],
4
+ "sourcesContent": ["/**\n * Inertia.js Vite Plugin\n *\n * This plugin provides two main features:\n *\n * 1. **Pages shorthand** - Transforms `pages: './Pages'` into a full `resolve` function\n * that uses `import.meta.glob` to load page components. This saves users from writing\n * boilerplate glob code in every project.\n *\n * 2. **SSR dev server** - During development, wraps the SSR entry file with server bootstrap\n * code and exposes an HTTP endpoint that Laravel can call to render pages server-side.\n * This eliminates the need to run a separate Node.js SSR server during development.\n *\n * The plugin is framework-agnostic - it detects which Inertia adapter (Vue, React, Svelte)\n * is being used by looking at import statements, then applies the appropriate transforms.\n * Custom frameworks can be added via the `frameworks` option.\n */\n\nimport { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport type { Plugin } from 'vite'\nimport { defaultFrameworks } from './frameworks/index'\nimport { transformPageResolution } from './pagesTransform'\nimport { handleSSRRequest, InertiaSSROptions, resolveSSREntry, SSR_ENDPOINT, SSR_ENTRY_CANDIDATES } from './ssr'\nimport { findInertiaAppExport, wrapWithServerBootstrap } from './ssrTransform'\nimport type { FrameworkConfig } from './types'\n\nexport type { FrameworkConfig, SSRTemplate } from './types'\nexport { InertiaSSROptions }\n\nexport interface InertiaPluginOptions {\n /**\n * SSR configuration. Pass a string for the entry path, an object for\n * additional options, or `false` to disable SSR entirely. Auto-detected\n * when not specified from:\n * - resources/js/ssr.{ts,tsx,js,jsx}\n * - src/ssr.{ts,tsx,js,jsx}\n * - resources/js/app.{ts,tsx,js,jsx}\n * - src/app.{ts,tsx,js,jsx}\n */\n ssr?: string | false | InertiaSSROptions\n\n /**\n * Custom framework configurations. Use this to add support for frameworks\n * beyond the built-in Vue, React, and Svelte adapters.\n *\n * @example\n * ```ts\n * inertia({\n * frameworks: {\n * package: '@inertiajs/solid',\n * extensions: ['.tsx', '.jsx'],\n * extractDefault: true,\n * ssr: (configureCall, options) => `\n * import createServer from '@inertiajs/solid/server'\n * const render = await ${configureCall}\n * createServer((page) => render(page)${options})\n * `,\n * }\n * })\n * ```\n */\n frameworks?: FrameworkConfig | FrameworkConfig[]\n}\n\n/**\n * Normalize the frameworks option into a record keyed by package name.\n */\nfunction toFrameworkRecord(input?: FrameworkConfig | FrameworkConfig[]): Record<string, FrameworkConfig> {\n if (!input) {\n return {}\n }\n\n const configs = Array.isArray(input) ? input : [input]\n\n return Object.fromEntries(configs.map((config) => [config.package, config]))\n}\n\nexport default function inertia(options: InertiaPluginOptions = {}): Plugin {\n const ssrDisabled = options.ssr === false\n const ssr = typeof options.ssr === 'string' ? { entry: options.ssr } : options.ssr || {}\n const frameworks = { ...defaultFrameworks, ...toFrameworkRecord(options.frameworks) }\n\n let entry: string | null = null\n\n return {\n name: '@inertiajs/vite',\n\n config(config, env) {\n if (ssrDisabled || !env.isSsrBuild) {\n return\n }\n\n const root = config.root ?? process.cwd()\n const ssrEntry = ssr.entry ?? SSR_ENTRY_CANDIDATES.find((candidate) => existsSync(resolve(root, candidate)))\n\n return {\n build: {\n sourcemap: ssr.sourcemap !== false ? (config.build?.sourcemap ?? true) : undefined,\n rollupOptions: ssrEntry\n ? {\n input: config.build?.rollupOptions?.input ?? ssrEntry,\n }\n : undefined,\n },\n }\n },\n\n configResolved(config) {\n if (ssrDisabled) {\n return\n }\n\n entry = resolveSSREntry(ssr, config)\n\n if (entry && config.build?.ssr) {\n config.logger.info(`Inertia SSR entry: ${entry}`)\n }\n },\n\n transform(code, id, options) {\n if (!/\\.[jt]sx?$/.test(id)) {\n return null\n }\n\n let result = code\n\n if (!ssrDisabled && options?.ssr && findInertiaAppExport(result)) {\n result =\n wrapWithServerBootstrap(\n result,\n { port: ssr.port, cluster: ssr.cluster, handleErrors: ssr.handleErrors },\n frameworks,\n ) ?? result\n }\n\n return transformPageResolution(result, frameworks) ?? (result !== code ? result : null)\n },\n\n configureServer(server) {\n if (!entry) {\n return\n }\n\n server.middlewares.use(SSR_ENDPOINT, async (req, res, next) => {\n if (req.method !== 'POST') {\n return next()\n }\n\n await handleSSRRequest(server, entry!, req, res, ssr.handleErrors ?? true)\n })\n\n server.config.logger.info(`Inertia SSR dev endpoint: ${SSR_ENDPOINT}`)\n },\n }\n}\n", "/**\n * React Framework Configuration\n *\n * This file defines how the Vite plugin handles React applications.\n * It serves as a reference for creating custom framework configurations.\n *\n * The SSR template shows what the plugin generates. For a user's SSR entry:\n *\n * ```js\n * import { createInertiaApp } from '@inertiajs/react'\n *\n * createInertiaApp({\n * resolve: (name) => resolvePageComponent(name),\n * })\n * ```\n *\n * In production, the plugin transforms it to:\n *\n * ```js\n * import { createInertiaApp } from '@inertiajs/react'\n * import createServer from '@inertiajs/react/server'\n * import { renderToString } from 'react-dom/server'\n *\n * const render = await createInertiaApp({\n * resolve: (name) => resolvePageComponent(name),\n * })\n *\n * createServer((page) => render(page, renderToString))\n * ```\n *\n * In development, it exports the render function directly for the Vite dev server.\n */\n\nimport type { FrameworkConfig } from '../types'\n\nexport const config: FrameworkConfig = {\n // Package name used to detect React usage via import statements\n package: '@inertiajs/react',\n\n // React components can use either .tsx (TypeScript) or .jsx\n // The plugin tries .tsx first, then falls back to .jsx\n extensions: ['.tsx', '.jsx'],\n\n // React components are exported as `export default`, so we need to extract .default\n extractDefault: true,\n\n // SSR template that wraps the createInertiaApp call with server bootstrap code\n // Uses import.meta.env.PROD to skip the standalone server in dev mode\n ssr: (configureCall, options) => `\nimport createServer from '@inertiajs/react/server'\nimport { renderToString } from 'react-dom/server'\n\nconst render = await ${configureCall}\n\nconst renderPage = (page) => render(page, renderToString)\n\nif (import.meta.env.PROD) {\n createServer(renderPage${options})\n}\n\nexport default renderPage\n`,\n}\n", "/**\n * Svelte Framework Configuration\n *\n * This file defines how the Vite plugin handles Svelte applications.\n * It serves as a reference for creating custom framework configurations.\n *\n * The SSR template shows what the plugin generates. For a user's SSR entry:\n *\n * ```js\n * import { createInertiaApp } from '@inertiajs/svelte'\n *\n * createInertiaApp({\n * resolve: (name) => resolvePageComponent(name),\n * })\n * ```\n *\n * The plugin transforms it to:\n *\n * ```js\n * import { createInertiaApp } from '@inertiajs/svelte'\n * import createServer from '@inertiajs/svelte/server'\n * import { render } from 'svelte/server'\n *\n * const ssr = await createInertiaApp({\n * resolve: (name) => resolvePageComponent(name),\n * })\n *\n * const renderPage = (page) => ssr(page, render)\n *\n * // Only start server in production\n * if (import.meta.env.PROD) {\n * createServer(renderPage)\n * }\n *\n * export default renderPage\n * ```\n */\n\nimport type { FrameworkConfig } from '../types'\n\nexport const config: FrameworkConfig = {\n // Package name used to detect Svelte usage via import statements\n package: '@inertiajs/svelte',\n\n // Svelte components use .svelte extension\n extensions: ['.svelte'],\n\n // Svelte components ARE the module - no .default extraction needed\n // This is different from Vue/React where components use `export default`\n extractDefault: false,\n\n // SSR template that wraps the createInertiaApp call with server bootstrap code\n // Uses import.meta.env.PROD to skip the standalone server in dev mode\n // Note: Svelte uses a different variable name (ssr) and render function import\n ssr: (configureCall, options) => `\nimport createServer from '@inertiajs/svelte/server'\nimport { render } from 'svelte/server'\n\nconst ssr = await ${configureCall}\n\nconst renderPage = (page) => ssr(page, render)\n\nif (import.meta.env.PROD) {\n createServer(renderPage${options})\n}\n\nexport default renderPage\n`,\n}\n", "/**\n * Vue Framework Configuration\n *\n * This file defines how the Vite plugin handles Vue applications.\n * It serves as a reference for creating custom framework configurations.\n *\n * The SSR template shows what the plugin generates. For a user's SSR entry:\n *\n * ```js\n * import { createInertiaApp } from '@inertiajs/vue3'\n *\n * createInertiaApp({\n * resolve: (name) => resolvePageComponent(name),\n * })\n * ```\n *\n * The plugin transforms it to:\n *\n * ```js\n * import { createInertiaApp } from '@inertiajs/vue3'\n * import createServer from '@inertiajs/vue3/server'\n * import { renderToString } from 'vue/server-renderer'\n *\n * const render = await createInertiaApp({\n * resolve: (name) => resolvePageComponent(name),\n * })\n *\n * const renderPage = (page) => render(page, renderToString)\n *\n * // Only start server in production\n * if (import.meta.env.PROD) {\n * createServer(renderPage)\n * }\n *\n * export default renderPage\n * ```\n */\n\nimport type { FrameworkConfig } from '../types'\n\nexport const config: FrameworkConfig = {\n // Package name used to detect Vue usage via import statements\n package: '@inertiajs/vue3',\n\n // Vue single-file components use .vue extension\n extensions: ['.vue'],\n\n // Vue components are exported as `export default`, so we need to extract .default\n extractDefault: true,\n\n // SSR template that wraps the createInertiaApp call with server bootstrap code\n // Uses import.meta.env.PROD to skip the standalone server in dev mode\n ssr: (configureCall, options) => `\nimport createServer from '@inertiajs/vue3/server'\nimport { renderToString } from 'vue/server-renderer'\n\nconst render = await ${configureCall}\n\nconst renderPage = (page) => render(page, renderToString)\n\nif (import.meta.env.PROD) {\n createServer(renderPage${options})\n}\n\nexport default renderPage\n`,\n}\n", "/**\n * Framework Registry\n *\n * This module exports the default framework configurations for Vue, React, and Svelte.\n * The plugin uses this registry to detect which framework is being used and apply\n * the appropriate transforms.\n *\n * Custom frameworks can be added via the `frameworks` plugin option, which will\n * be merged with these defaults (custom configs override defaults with the same package name).\n */\n\nimport type { FrameworkConfig } from '../types'\nimport { config as react } from './react'\nimport { config as svelte } from './svelte'\nimport { config as vue } from './vue'\n\n/**\n * Array of all built-in framework configurations.\n * Order doesn't matter - detection is based on import statements.\n */\nconst frameworks: FrameworkConfig[] = [vue, react, svelte]\n\n/**\n * Framework configs keyed by package name for efficient lookup.\n *\n * Example:\n * {\n * '@inertiajs/vue3': { package: '@inertiajs/vue3', extensions: ['.vue'], ... },\n * '@inertiajs/react': { package: '@inertiajs/react', extensions: ['.tsx', '.jsx'], ... },\n * '@inertiajs/svelte': { package: '@inertiajs/svelte', extensions: ['.svelte'], ... }\n * }\n */\nexport const defaultFrameworks: Record<string, FrameworkConfig> = Object.fromEntries(\n frameworks.map((config) => [config.package, config]),\n)\n", "/**\n * AST Utilities for Inertia Code Transforms\n *\n * Parses JavaScript/TypeScript code using Vite's built-in `parseAst` (Rollup's parser)\n * and provides methods to find Inertia-specific patterns like `createInertiaApp()` calls,\n * framework detection, and property extraction.\n */\n\nimport type {\n CallExpression,\n ExpressionStatement,\n Identifier,\n ObjectExpression,\n Program,\n Property,\n SimpleCallExpression,\n} from 'estree'\nimport { parseAst } from 'vite'\nimport type { FrameworkConfig } from './types'\n\n/**\n * ESTree nodes augmented with the `start`/`end` positions Rollup's parser adds.\n */\nexport type NodeWithPos<T> = T & { start: number; end: number }\n\nconst INERTIA_APP_FUNCTION = 'createInertiaApp'\nconst CREATE_SERVER_FUNCTION = 'createServer'\n\n/** A top-level `createInertiaApp()` expression statement with position info. */\nexport interface InertiaStatement {\n statement: NodeWithPos<ExpressionStatement>\n call: NodeWithPos<SimpleCallExpression>\n}\n\n/** Position info for the first argument of a `createInertiaApp()` call. */\nexport interface InertiaCallOptions {\n start: number\n end: number\n isEmpty: boolean\n}\n\n/** Wraps a parsed AST with methods to find Inertia-specific patterns. */\nexport class ParsedCode {\n private constructor(private ast: Program) {}\n\n /** Returns null if parsing fails (e.g. non-JS file content). */\n static from(code: string): ParsedCode | null {\n try {\n return new ParsedCode(parseAst(code))\n } catch {\n return null\n }\n }\n\n get importSources(): string[] {\n const sources: string[] = []\n\n for (const node of this.ast.body) {\n if (node.type === 'ImportDeclaration') {\n sources.push(node.source.value as string)\n }\n }\n\n return sources\n }\n\n detectFramework(frameworks: Record<string, FrameworkConfig>): { name: string; config: FrameworkConfig } | null {\n const name = this.importSources.find((source) => source in frameworks)\n\n return name ? { name, config: frameworks[name] } : null\n }\n\n /**\n * Find a top-level `createInertiaApp()` expression statement.\n * Only matches bare calls, not `export default createInertiaApp()`.\n */\n get inertiaStatement(): InertiaStatement | null {\n for (const node of this.ast.body) {\n if (node.type !== 'ExpressionStatement') {\n continue\n }\n\n const statement = node as NodeWithPos<ExpressionStatement>\n let expr = statement.expression as { type: string; argument?: unknown; start: number; end: number }\n\n // Handle `await createInertiaApp()` - unwrap the await to get the call\n if (expr.type === 'AwaitExpression') {\n expr = expr.argument as typeof expr\n }\n\n if (expr.type === 'CallExpression') {\n const call = expr as NodeWithPos<SimpleCallExpression>\n\n if (this.isInertiaCall(call)) {\n return { statement, call }\n }\n }\n }\n\n return null\n }\n\n /** Find a top-level `createServer()` call (not nested in exports). */\n get createServerStatement(): NodeWithPos<ExpressionStatement> | null {\n for (const node of this.ast.body) {\n if (node.type !== 'ExpressionStatement') {\n continue\n }\n\n const statement = node as NodeWithPos<ExpressionStatement>\n const expr = statement.expression\n\n if (expr.type === 'CallExpression') {\n const call = expr as SimpleCallExpression\n\n if (call.callee.type === 'Identifier' && (call.callee as Identifier).name === CREATE_SERVER_FUNCTION) {\n return statement\n }\n }\n }\n\n return null\n }\n\n /**\n * Find all `createInertiaApp()` calls, including those nested inside exports.\n */\n get inertiaCalls(): CallExpression[] {\n const calls: CallExpression[] = []\n\n this.walkAst(this.ast, (node) => {\n if (node.type === 'CallExpression' && this.isInertiaCall(node as CallExpression)) {\n calls.push(node as CallExpression)\n }\n })\n\n return calls\n }\n\n get pagesProperty(): NodeWithPos<Property> | null {\n for (const call of this.inertiaCalls) {\n if (call.arguments.length === 0 || call.arguments[0].type !== 'ObjectExpression') {\n continue\n }\n\n // Look for a `pages` property in the options object\n for (const prop of (call.arguments[0] as ObjectExpression).properties) {\n if (prop.type !== 'Property' || prop.key.type !== 'Identifier' || prop.key.name !== 'pages') {\n continue\n }\n\n return prop as NodeWithPos<Property>\n }\n }\n\n return null\n }\n\n /** Find a `createInertiaApp()` call that has no `pages` or `resolve` property yet. */\n get callWithoutResolver(): { callEnd: number; options?: InertiaCallOptions } | null {\n for (const call of this.inertiaCalls) {\n const callWithPos = call as NodeWithPos<CallExpression>\n\n // Empty call: createInertiaApp()\n if (call.arguments.length === 0) {\n return { callEnd: callWithPos.end }\n }\n\n // Non-object argument - can't inject resolver\n if (call.arguments[0].type !== 'ObjectExpression') {\n continue\n }\n\n const obj = call.arguments[0] as NodeWithPos<ObjectExpression>\n\n const hasResolver = obj.properties.some(\n (p) =>\n p.type === 'Property' && p.key.type === 'Identifier' && (p.key.name === 'pages' || p.key.name === 'resolve'),\n )\n\n if (hasResolver) {\n continue\n }\n\n return {\n callEnd: callWithPos.end,\n options: { start: obj.start, end: obj.end, isEmpty: obj.properties.length === 0 },\n }\n }\n\n return null\n }\n\n private isInertiaCall(node: CallExpression | SimpleCallExpression): boolean {\n return node.callee.type === 'Identifier' && (node.callee as Identifier).name === INERTIA_APP_FUNCTION\n }\n\n private walkAst(node: unknown, callback: (node: { type: string }) => void): void {\n if (!node || typeof node !== 'object') {\n return\n }\n\n if ('type' in node) {\n callback(node as { type: string })\n }\n\n for (const value of Object.values(node as Record<string, unknown>)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n this.walkAst(item, callback)\n }\n } else {\n this.walkAst(value, callback)\n }\n }\n }\n}\n\n/**\n * Supports regular strings and simple template literals without expressions.\n */\nexport function extractString(node: Property['value']): string | undefined {\n if (node.type === 'Literal' && typeof node.value === 'string') {\n return node.value\n }\n\n // Template literal without expressions: `./Pages`\n if (node.type === 'TemplateLiteral' && node.expressions.length === 0) {\n return node.quasis[0].value.cooked ?? node.quasis[0].value.raw\n }\n\n return undefined\n}\n\n/** Each element is passed through `extractString`, non-strings are skipped. */\nexport function extractStringArray(node: Property['value']): string[] | undefined {\n if (node.type !== 'ArrayExpression') {\n return undefined\n }\n\n const strings = node.elements\n .map((el) => (el ? extractString(el as Property['value']) : undefined))\n .filter((s): s is string => s !== undefined)\n\n return strings.length > 0 ? strings : undefined\n}\n\nexport function extractBoolean(node: Property['value']): boolean | undefined {\n if (node.type === 'Literal' && typeof node.value === 'boolean') {\n return node.value\n }\n\n return undefined\n}\n", "/**\n * Pages Transform\n *\n * This module transforms the `pages` shorthand into a full `resolve` function.\n * Instead of writing verbose glob code in every project, users can simply write:\n *\n * ```js\n * createInertiaApp({ pages: './Pages' })\n * ```\n *\n * Which gets transformed into:\n *\n * ```js\n * createInertiaApp({\n * resolve: async (name, page) => {\n * const pages = import.meta.glob('./Pages/*.vue')\n * const module = await (pages[`./Pages/${name}.vue`])?.()\n * if (!module) throw new Error(`Page not found: ${name}`)\n * return module.default ?? module\n * }\n * })\n * ```\n *\n * The transform also supports advanced configuration:\n *\n * ```js\n * createInertiaApp({\n * pages: {\n * path: './Pages',\n * extension: '.tsx',\n * lazy: true,\n * transform: (name, page) => name.replace('/', '-')\n * }\n * })\n * ```\n */\n\nimport type { Property } from 'estree'\nimport { type NodeWithPos, ParsedCode, extractBoolean, extractString, extractStringArray } from './astUtils'\nimport type { FrameworkConfig } from './types'\n\n/** Returns the transformed code, or null if no transformation was needed. */\nexport function transformPageResolution(code: string, frameworks: Record<string, FrameworkConfig>): string | null {\n if (!code.includes('InertiaApp')) {\n return null\n }\n\n const parsed = ParsedCode.from(code)\n\n if (!parsed) {\n return null\n }\n\n const framework = parsed.detectFramework(frameworks)\n\n if (!framework) {\n return null\n }\n\n const extensions = framework.config.extensions\n const extractDefault = framework.config.extractDefault ?? true\n\n if (parsed.pagesProperty) {\n return replacePages(code, parsed.pagesProperty, extensions, extractDefault)\n }\n\n if (parsed.callWithoutResolver) {\n return injectResolver(code, parsed.callWithoutResolver, extensions, extractDefault)\n }\n\n return null\n}\n\n/**\n * Replace the `pages` property with a generated `resolve` function.\n *\n * Input: `{ pages: './Pages', title: t => t }`\n * Output: `{ resolve: async (name, page) => { ... }, title: t => t }`\n */\nfunction replacePages(\n code: string,\n property: NodeWithPos<Property>,\n defaultExtensions: string[],\n extractDefault: boolean,\n): string {\n const config = extractPagesConfig(property.value, code)\n\n if (!config) {\n return code\n }\n\n const extensions = config.extensions\n ? Array.isArray(config.extensions)\n ? config.extensions\n : [config.extensions]\n : defaultExtensions\n\n const eager = !(config.lazy ?? true)\n\n const resolver = config.directory\n ? buildResolver(config.directory.replace(/\\/$/, ''), extensions, extractDefault, eager, config.transform)\n : buildDefaultResolver(extensions, extractDefault, eager)\n\n return code.slice(0, property.start) + resolver + code.slice(property.end)\n}\n\n/**\n * Inject a default resolver into a call that doesn't have one.\n *\n * Handles three cases:\n * 1. Empty call: `createInertiaApp()` becomes `createInertiaApp({ resolve: ... })`\n * 2. Empty object: `createInertiaApp({})` becomes `createInertiaApp({ resolve: ... })`\n * 3. Other options: `createInertiaApp({a})` becomes `createInertiaApp({ resolve: ..., a})`\n */\nfunction injectResolver(\n code: string,\n call: { callEnd: number; options?: { start: number; end: number; isEmpty: boolean } },\n extensions: string[],\n extractDefault: boolean,\n): string {\n const resolver = buildDefaultResolver(extensions, extractDefault)\n\n if (!call.options) {\n return code.slice(0, call.callEnd - 1) + `{ ${resolver} })` + code.slice(call.callEnd)\n }\n\n if (call.options.isEmpty) {\n return code.slice(0, call.options.start) + `{ ${resolver} }` + code.slice(call.options.end)\n }\n\n return code.slice(0, call.options.start + 1) + ` ${resolver},` + code.slice(call.options.start + 1)\n}\n\n/** The parsed representation of a `pages` property value. */\ninterface PagesConfig {\n directory?: string\n extensions?: string | string[]\n transform?: string\n lazy?: boolean\n}\n\n/**\n * Extract configuration from the `pages` property value.\n *\n * Supports two formats:\n * 1. String: `pages: './Pages'`\n * 2. Object: `pages: { path: './Pages', extension: '.vue', lazy: true, transform: fn }`\n */\nfunction extractPagesConfig(node: Property['value'], code: string): PagesConfig | null {\n const str = extractString(node)\n\n if (str) {\n return { directory: str }\n }\n\n if (node.type !== 'ObjectExpression') {\n return null\n }\n\n let directory: string | undefined\n let extensions: string | string[] | undefined\n let transform: string | undefined\n let lazy: boolean | undefined\n\n for (const prop of node.properties) {\n if (prop.type !== 'Property' || prop.key.type !== 'Identifier') {\n continue\n }\n\n const key = prop.key.name\n const value = prop.value as NodeWithPos<Property['value']>\n\n if (key === 'path') {\n directory = extractString(value)\n } else if (key === 'extension') {\n extensions = extractString(value) ?? extractStringArray(value)\n } else if (key === 'transform') {\n transform = code.slice(value.start, value.end)\n } else if (key === 'lazy') {\n lazy = extractBoolean(value)\n }\n }\n\n return { directory, extensions, transform, lazy }\n}\n\nfunction buildResolver(\n directories: string | string[],\n extensions: string[],\n extractDefault: boolean,\n eager: boolean,\n transform?: string,\n): string {\n const dirs = Array.isArray(directories) ? directories : [directories]\n\n const globs = dirs.map((d) => buildGlob(d, extensions))\n const glob = globs.length === 1 ? `'${globs[0]}'` : `['${globs.join(\"', '\")}']`\n\n const nameVar = transform ? 'resolvedName' : 'name'\n const lookup = dirs.flatMap((d) => extensions.map((ext) => `pages[\\`${d}/\\${${nameVar}}${ext}\\`]`)).join(' || ')\n\n const transformLine = transform ? `const resolvedName = (${transform})(name, page)\\n ` : ''\n\n const returnValue = extractDefault ? 'module.default ?? module' : 'module'\n\n const globOptions = `, { eager: ${eager} }`\n const moduleLookup = eager ? lookup : `await (${lookup})?.()`\n\n return `resolve: async (name, page) => {\n ${transformLine}const pages = import.meta.glob(${glob}${globOptions})\n const module = ${moduleLookup}\n if (!module) throw new Error(\\`Page not found: \\${name}\\`)\n return ${returnValue}\n }`\n}\n\nfunction buildDefaultResolver(extensions: string[], extractDefault: boolean, eager: boolean = false): string {\n return buildResolver(['./pages', './Pages'], extensions, extractDefault, eager)\n}\n\nfunction buildGlob(directory: string, extensions: string[]): string {\n const ext = extensions.length === 1 ? extensions[0] : `{${extensions.join(',')}}`\n\n return `${directory}/**/*${ext}`\n}\n", "/**\n * SSR Dev Server\n *\n * This module handles SSR rendering during development. Instead of running\n * a separate Node.js SSR server, the Vite dev server exposes an HTTP endpoint\n * that Laravel can call to render pages server-side.\n *\n * How it works:\n * 1. Laravel detects that the Vite dev server is running\n * 2. Laravel POSTs the page data to `/__inertia_ssr`\n * 3. This module loads the SSR entry file via Vite's SSR module loader\n * 4. The entry file's default export is called with the page data\n * 5. The rendered HTML is returned to Laravel\n *\n * This approach provides:\n * - Hot Module Replacement (HMR) for SSR code during development\n * - No need to restart a separate SSR server when code changes\n * - Automatic TypeScript/JSX transformation via Vite\n */\n\nimport { classifySSRError, formatConsoleError } from '@inertiajs/core/ssrErrors'\nimport { existsSync } from 'node:fs'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { resolve } from 'node:path'\nimport type { ResolvedConfig, ViteDevServer } from 'vite'\nimport { collectCSSFromModuleGraph } from './css'\n\n/** Options for the SSR dev server and production builds. */\nexport interface InertiaSSROptions {\n /**\n * Path to the SSR entry file. Auto-detected when not specified.\n */\n entry?: string\n\n /**\n * Port number for the SSR server (used in production builds).\n */\n port?: number\n\n /**\n * Enable cluster mode for the SSR server (used in production builds).\n */\n cluster?: boolean\n\n /**\n * When enabled, SSR errors are formatted with hints instead of thrown raw.\n * Defaults to true.\n */\n handleErrors?: boolean\n\n /**\n * Enable sourcemaps for SSR builds so error stacks map to original files.\n * Defaults to true.\n */\n sourcemap?: boolean\n}\n\nexport const SSR_ENDPOINT = '/__inertia_ssr'\n\nexport const SSR_ENTRY_CANDIDATES = [\n 'resources/js/ssr.ts',\n 'resources/js/ssr.tsx',\n 'resources/js/ssr.js',\n 'resources/js/ssr.jsx',\n 'src/ssr.ts',\n 'src/ssr.tsx',\n 'src/ssr.js',\n 'src/ssr.jsx',\n 'resources/js/app.ts',\n 'resources/js/app.tsx',\n 'resources/js/app.js',\n 'resources/js/app.jsx',\n 'src/app.ts',\n 'src/app.tsx',\n 'src/app.js',\n 'src/app.jsx',\n]\n\nexport function resolveSSREntry(options: InertiaSSROptions, config: ResolvedConfig): string | null {\n if (options.entry) {\n if (existsSync(resolve(config.root, options.entry))) {\n return options.entry\n }\n\n config.logger.warn(`Inertia SSR entry not found: ${options.entry}`)\n\n return null\n }\n\n return SSR_ENTRY_CANDIDATES.find((path) => existsSync(resolve(config.root, path))) ?? null\n}\n\nexport async function handleSSRRequest(\n server: ViteDevServer,\n entry: string,\n req: IncomingMessage,\n res: ServerResponse,\n handleErrors: boolean = true,\n): Promise<void> {\n let component: string | undefined\n let url: string | undefined\n\n // We temporarily override console.warn to suppress Vue's verbose component\n // trace warnings during SSR, and show our own cleaner error output instead.\n const originalWarn = console.warn\n const suppressedWarnings: string[] = []\n\n console.warn = (...args: unknown[]) => {\n const message = args[0]?.toString() ?? ''\n\n if (message.includes('[Vue warn]') || message.includes('at <')) {\n if (handleErrors) {\n suppressedWarnings.push(args.map(String).join(' '))\n }\n\n return\n }\n\n originalWarn.apply(console, args)\n }\n\n try {\n const page = await readRequestBody<{ component: string; url: string }>(req)\n component = page.component\n url = page.url\n const start = performance.now()\n\n const render = await loadRenderFunction(server, entry)\n const result = await render(page)\n\n if (!result || typeof result.body !== 'string') {\n throw new Error(`SSR render must return { head: string[], body: string }`)\n }\n\n const cssLinks = collectCSSFromModuleGraph(server, entry)\n result.head = [...cssLinks, ...result.head]\n\n logSSRRequest(server, page.component, start)\n\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify(result))\n } catch (error) {\n handleSSRError(server, res, error as Error, component, url, handleErrors, suppressedWarnings)\n } finally {\n console.warn = originalWarn\n }\n}\n\nasync function loadRenderFunction(\n server: ViteDevServer,\n entry: string,\n): Promise<(page: unknown) => Promise<{ head: string[]; body: string }>> {\n const module = await server.ssrLoadModule(entry)\n const render = await Promise.resolve(module.default)\n\n if (typeof render !== 'function') {\n throw new Error(`SSR entry \"${entry}\" must export a render function`)\n }\n\n return render\n}\n\nfunction readRequestBody<T>(req: IncomingMessage): Promise<T> {\n return new Promise((resolve, reject) => {\n let data = ''\n\n req.on('data', (chunk) => (data += chunk))\n\n req.on('end', () => {\n if (!data.trim()) {\n reject(new Error('Request body is empty'))\n return\n }\n\n try {\n resolve(JSON.parse(data))\n } catch (error) {\n reject(new Error(`Invalid JSON in request body: ${error instanceof Error ? error.message : 'Unknown error'}`))\n }\n })\n\n req.on('error', reject)\n })\n}\n\n/**\n * Log an SSR request to the Vite dev server console.\n *\n * Output format: `2024-01-15 10:30:45 SSR Users/Index 12.34ms`\n */\nfunction logSSRRequest(server: ViteDevServer, component: string, start: number): void {\n const duration = (performance.now() - start).toFixed(2)\n const timestamp = new Date().toISOString().replace('T', ' ').slice(0, 19)\n\n server.config.logger.info(`\\x1b[32m${timestamp}\\x1b[0m SSR ${component} \\x1b[90m${duration}ms\\x1b[0m`)\n}\n\nfunction handleSSRError(\n server: ViteDevServer,\n res: ServerResponse,\n error: Error,\n component?: string,\n url?: string,\n handleErrors: boolean = true,\n suppressedWarnings: string[] = [],\n): void {\n server.ssrFixStacktrace(error)\n\n if (!handleErrors) {\n throw error\n }\n\n const classified = classifySSRError(error, component, url)\n\n server.config.logger.error(formatConsoleError(classified, server.config.root, handleErrors, suppressedWarnings))\n\n res.setHeader('Content-Type', 'application/json')\n res.statusCode = 500\n res.end(JSON.stringify(classified))\n}\n", "/**\n * SSR CSS Collection\n *\n * Collects CSS dependencies from Vite's module graph to prevent FOUC\n * (Flash of Unstyled Content) during SSR development.\n *\n * In dev mode, Vite normally injects CSS via JavaScript on the client side.\n * When SSR is enabled, the server-rendered HTML arrives before any JS executes,\n * causing unstyled content to flash briefly. This module traverses the SSR\n * environment's module graph starting from the entry to find all CSS\n * dependencies, then generates <link> tags so the browser fetches styles\n * immediately with the initial HTML.\n *\n * The generated <link> tags include `data-vite-dev-id` attributes so Vite's\n * client JS can deduplicate them and avoid injecting duplicate <style> tags.\n */\n\nimport { resolve } from 'node:path'\nimport type { EnvironmentModuleNode, ViteDevServer } from 'vite'\n\nexport function collectCSSFromModuleGraph(server: ViteDevServer, entry: string): string[] {\n const entryModule = resolveEntryModule(server, entry)\n\n if (!entryModule) {\n return []\n }\n\n const cssModules = collectCSSModules(entryModule)\n\n if (cssModules.length === 0) {\n return []\n }\n\n const origin = resolveDevServerOrigin(server)\n const base = server.config.base || '/'\n const basePrefix = base === '/' ? '' : base\n\n return cssModules.map(({ url, id }) => {\n const href = `${origin}${basePrefix}${url}`\n const devId = id ? ` data-vite-dev-id=\"${id}\"` : ''\n\n return `<link rel=\"stylesheet\" href=\"${href}\"${devId}>`\n })\n}\n\nfunction resolveEntryModule(server: ViteDevServer, entry: string): EnvironmentModuleNode | undefined {\n const resolvedEntry = resolve(server.config.root, entry)\n\n return server.environments.ssr.moduleGraph.getModuleById(resolvedEntry)\n}\n\nfunction collectCSSModules(entryModule: EnvironmentModuleNode): { url: string; id: string | null }[] {\n const cssModules: { url: string; id: string | null }[] = []\n const visited = new Set<EnvironmentModuleNode>()\n\n function traverse(mod: EnvironmentModuleNode): void {\n if (visited.has(mod)) {\n return\n }\n\n visited.add(mod)\n\n if (isCSSRequest(mod.url)) {\n cssModules.push({ url: mod.url, id: mod.id })\n }\n\n for (const imported of mod.importedModules) {\n traverse(imported)\n }\n }\n\n traverse(entryModule)\n\n return cssModules\n}\n\nconst CSS_EXTENSIONS = /\\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\\?)/\n\nfunction isCSSRequest(url: string): boolean {\n return CSS_EXTENSIONS.test(url)\n}\n\nfunction resolveDevServerOrigin(server: ViteDevServer): string {\n if (server.resolvedUrls?.local[0]) {\n return server.resolvedUrls.local[0].replace(/\\/$/, '')\n }\n\n const protocol = server.config.server.https ? 'https' : 'http'\n const port = server.config.server.port ?? 5173\n\n return `${protocol}://localhost:${port}`\n}\n", "/**\n * SSR Transform\n *\n * Transforms the SSR entry file by wrapping `createInertiaApp()` with\n * framework-specific server bootstrap code, so users don't need to\n * write the boilerplate manually.\n */\n\nimport { ParsedCode } from './astUtils'\nimport type { FrameworkConfig, SSROptions } from './types'\n\n/**\n * Returns empty string if no options, otherwise `, {\"port\":13715}`.\n */\nfunction formatSSROptions(options: SSROptions): string {\n const entries = Object.entries(options).filter(([, v]) => v !== undefined)\n\n return entries.length > 0 ? `, ${JSON.stringify(Object.fromEntries(entries))}` : ''\n}\n\n/**\n * Quick check for a top-level call that needs SSR wrapping.\n */\nexport function findInertiaAppExport(code: string): boolean {\n const parsed = ParsedCode.from(code)\n return !!(parsed?.inertiaStatement || parsed?.createServerStatement)\n}\n\n/**\n * Wrap `createInertiaApp()` or `createServer()` with the framework's SSR bootstrap.\n */\nexport function wrapWithServerBootstrap(\n code: string,\n options: SSROptions,\n frameworks: Record<string, FrameworkConfig>,\n): string | null {\n const parsed = ParsedCode.from(code)\n\n if (!parsed) {\n return null\n }\n\n if (parsed.inertiaStatement) {\n const framework = parsed.detectFramework(frameworks)\n\n if (!framework?.config.ssr) {\n return null\n }\n\n const { statement, call } = parsed.inertiaStatement\n const configureCall = code.slice(call.start, call.end)\n const ssrCode = framework.config.ssr(configureCall, formatSSROptions(options)).trim()\n\n return code.slice(0, statement.start) + ssrCode + code.slice(statement.end)\n }\n\n if (parsed.createServerStatement) {\n const statement = parsed.createServerStatement\n const args = (statement.expression as unknown as { arguments: Array<{ start: number; end: number }> }).arguments\n const callback = code.slice(args[0].start, args[0].end)\n const trailingArgs = code.slice(args[0].end, args[args.length - 1].end)\n\n const replacement = `const renderPage = ${callback}\n\nif (import.meta.env.PROD) {\n createServer(renderPage${trailingArgs})\n}\n\nexport default renderPage`\n\n return code.slice(0, statement.start) + replacement + code.slice(statement.end)\n }\n\n return null\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["existsSync", "resolve", "config", "config", "config", "frameworks", "frameworks", "config", "resolve", "config", "resolve", "frameworks", "config", "frameworks", "existsSync", "resolve", "options"]
7
+ }
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@inertiajs/vite",
3
+ "version": "3.0.0-beta.1",
4
+ "license": "MIT",
5
+ "description": "Vite plugin for Inertia.js with SSR dev mode support.",
6
+ "contributors": [
7
+ "Pascal Baljet <pascal@laravel.com>"
8
+ ],
9
+ "homepage": "https://inertiajs.com/",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/inertiajs/inertia.git",
13
+ "directory": "packages/vite"
14
+ },
15
+ "bugs": {
16
+ "url": "https://github.com/inertiajs/inertia/issues"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "types"
21
+ ],
22
+ "type": "module",
23
+ "main": "dist/index.js",
24
+ "types": "types/index.d.ts",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./types/index.d.ts",
28
+ "import": "./dist/index.js"
29
+ }
30
+ },
31
+ "dependencies": {
32
+ "@inertiajs/core": "3.0.0-beta.1"
33
+ },
34
+ "peerDependencies": {
35
+ "vite": "^6.0.0 || ^7.0.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/estree": "^1.0.8",
39
+ "@types/node": "^24.10.13",
40
+ "esbuild": "^0.27.3",
41
+ "esbuild-node-externals": "^1.20.1",
42
+ "typescript": "^5.9.3",
43
+ "vite": "^7.3.1",
44
+ "vitest": "^3.2.4"
45
+ },
46
+ "scripts": {
47
+ "build": "pnpm clean && ./build.js && tsc",
48
+ "clean": "rm -rf types && rm -rf dist",
49
+ "dev": "pnpx concurrently -c \"#ffcf00,#3178c6\" \"pnpm dev:build\" \"pnpm dev:types\" --names build,types",
50
+ "dev:build": "./build.js --watch",
51
+ "dev:types": "tsc --watch --preserveWatchOutput",
52
+ "test": "vitest run"
53
+ }
54
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * AST Utilities for Inertia Code Transforms
3
+ *
4
+ * Parses JavaScript/TypeScript code using Vite's built-in `parseAst` (Rollup's parser)
5
+ * and provides methods to find Inertia-specific patterns like `createInertiaApp()` calls,
6
+ * framework detection, and property extraction.
7
+ */
8
+ import type { CallExpression, ExpressionStatement, Property, SimpleCallExpression } from 'estree';
9
+ import type { FrameworkConfig } from './types';
10
+ /**
11
+ * ESTree nodes augmented with the `start`/`end` positions Rollup's parser adds.
12
+ */
13
+ export type NodeWithPos<T> = T & {
14
+ start: number;
15
+ end: number;
16
+ };
17
+ /** A top-level `createInertiaApp()` expression statement with position info. */
18
+ export interface InertiaStatement {
19
+ statement: NodeWithPos<ExpressionStatement>;
20
+ call: NodeWithPos<SimpleCallExpression>;
21
+ }
22
+ /** Position info for the first argument of a `createInertiaApp()` call. */
23
+ export interface InertiaCallOptions {
24
+ start: number;
25
+ end: number;
26
+ isEmpty: boolean;
27
+ }
28
+ /** Wraps a parsed AST with methods to find Inertia-specific patterns. */
29
+ export declare class ParsedCode {
30
+ private ast;
31
+ private constructor();
32
+ /** Returns null if parsing fails (e.g. non-JS file content). */
33
+ static from(code: string): ParsedCode | null;
34
+ get importSources(): string[];
35
+ detectFramework(frameworks: Record<string, FrameworkConfig>): {
36
+ name: string;
37
+ config: FrameworkConfig;
38
+ } | null;
39
+ /**
40
+ * Find a top-level `createInertiaApp()` expression statement.
41
+ * Only matches bare calls, not `export default createInertiaApp()`.
42
+ */
43
+ get inertiaStatement(): InertiaStatement | null;
44
+ /** Find a top-level `createServer()` call (not nested in exports). */
45
+ get createServerStatement(): NodeWithPos<ExpressionStatement> | null;
46
+ /**
47
+ * Find all `createInertiaApp()` calls, including those nested inside exports.
48
+ */
49
+ get inertiaCalls(): CallExpression[];
50
+ get pagesProperty(): NodeWithPos<Property> | null;
51
+ /** Find a `createInertiaApp()` call that has no `pages` or `resolve` property yet. */
52
+ get callWithoutResolver(): {
53
+ callEnd: number;
54
+ options?: InertiaCallOptions;
55
+ } | null;
56
+ private isInertiaCall;
57
+ private walkAst;
58
+ }
59
+ /**
60
+ * Supports regular strings and simple template literals without expressions.
61
+ */
62
+ export declare function extractString(node: Property['value']): string | undefined;
63
+ /** Each element is passed through `extractString`, non-strings are skipped. */
64
+ export declare function extractStringArray(node: Property['value']): string[] | undefined;
65
+ export declare function extractBoolean(node: Property['value']): boolean | undefined;
package/types/css.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * SSR CSS Collection
3
+ *
4
+ * Collects CSS dependencies from Vite's module graph to prevent FOUC
5
+ * (Flash of Unstyled Content) during SSR development.
6
+ *
7
+ * In dev mode, Vite normally injects CSS via JavaScript on the client side.
8
+ * When SSR is enabled, the server-rendered HTML arrives before any JS executes,
9
+ * causing unstyled content to flash briefly. This module traverses the SSR
10
+ * environment's module graph starting from the entry to find all CSS
11
+ * dependencies, then generates <link> tags so the browser fetches styles
12
+ * immediately with the initial HTML.
13
+ *
14
+ * The generated <link> tags include `data-vite-dev-id` attributes so Vite's
15
+ * client JS can deduplicate them and avoid injecting duplicate <style> tags.
16
+ */
17
+ import type { ViteDevServer } from 'vite';
18
+ export declare function collectCSSFromModuleGraph(server: ViteDevServer, entry: string): string[];
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Framework Registry
3
+ *
4
+ * This module exports the default framework configurations for Vue, React, and Svelte.
5
+ * The plugin uses this registry to detect which framework is being used and apply
6
+ * the appropriate transforms.
7
+ *
8
+ * Custom frameworks can be added via the `frameworks` plugin option, which will
9
+ * be merged with these defaults (custom configs override defaults with the same package name).
10
+ */
11
+ import type { FrameworkConfig } from '../types';
12
+ /**
13
+ * Framework configs keyed by package name for efficient lookup.
14
+ *
15
+ * Example:
16
+ * {
17
+ * '@inertiajs/vue3': { package: '@inertiajs/vue3', extensions: ['.vue'], ... },
18
+ * '@inertiajs/react': { package: '@inertiajs/react', extensions: ['.tsx', '.jsx'], ... },
19
+ * '@inertiajs/svelte': { package: '@inertiajs/svelte', extensions: ['.svelte'], ... }
20
+ * }
21
+ */
22
+ export declare const defaultFrameworks: Record<string, FrameworkConfig>;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * React Framework Configuration
3
+ *
4
+ * This file defines how the Vite plugin handles React applications.
5
+ * It serves as a reference for creating custom framework configurations.
6
+ *
7
+ * The SSR template shows what the plugin generates. For a user's SSR entry:
8
+ *
9
+ * ```js
10
+ * import { createInertiaApp } from '@inertiajs/react'
11
+ *
12
+ * createInertiaApp({
13
+ * resolve: (name) => resolvePageComponent(name),
14
+ * })
15
+ * ```
16
+ *
17
+ * In production, the plugin transforms it to:
18
+ *
19
+ * ```js
20
+ * import { createInertiaApp } from '@inertiajs/react'
21
+ * import createServer from '@inertiajs/react/server'
22
+ * import { renderToString } from 'react-dom/server'
23
+ *
24
+ * const render = await createInertiaApp({
25
+ * resolve: (name) => resolvePageComponent(name),
26
+ * })
27
+ *
28
+ * createServer((page) => render(page, renderToString))
29
+ * ```
30
+ *
31
+ * In development, it exports the render function directly for the Vite dev server.
32
+ */
33
+ import type { FrameworkConfig } from '../types';
34
+ export declare const config: FrameworkConfig;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Svelte Framework Configuration
3
+ *
4
+ * This file defines how the Vite plugin handles Svelte applications.
5
+ * It serves as a reference for creating custom framework configurations.
6
+ *
7
+ * The SSR template shows what the plugin generates. For a user's SSR entry:
8
+ *
9
+ * ```js
10
+ * import { createInertiaApp } from '@inertiajs/svelte'
11
+ *
12
+ * createInertiaApp({
13
+ * resolve: (name) => resolvePageComponent(name),
14
+ * })
15
+ * ```
16
+ *
17
+ * The plugin transforms it to:
18
+ *
19
+ * ```js
20
+ * import { createInertiaApp } from '@inertiajs/svelte'
21
+ * import createServer from '@inertiajs/svelte/server'
22
+ * import { render } from 'svelte/server'
23
+ *
24
+ * const ssr = await createInertiaApp({
25
+ * resolve: (name) => resolvePageComponent(name),
26
+ * })
27
+ *
28
+ * const renderPage = (page) => ssr(page, render)
29
+ *
30
+ * // Only start server in production
31
+ * if (import.meta.env.PROD) {
32
+ * createServer(renderPage)
33
+ * }
34
+ *
35
+ * export default renderPage
36
+ * ```
37
+ */
38
+ import type { FrameworkConfig } from '../types';
39
+ export declare const config: FrameworkConfig;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Vue Framework Configuration
3
+ *
4
+ * This file defines how the Vite plugin handles Vue applications.
5
+ * It serves as a reference for creating custom framework configurations.
6
+ *
7
+ * The SSR template shows what the plugin generates. For a user's SSR entry:
8
+ *
9
+ * ```js
10
+ * import { createInertiaApp } from '@inertiajs/vue3'
11
+ *
12
+ * createInertiaApp({
13
+ * resolve: (name) => resolvePageComponent(name),
14
+ * })
15
+ * ```
16
+ *
17
+ * The plugin transforms it to:
18
+ *
19
+ * ```js
20
+ * import { createInertiaApp } from '@inertiajs/vue3'
21
+ * import createServer from '@inertiajs/vue3/server'
22
+ * import { renderToString } from 'vue/server-renderer'
23
+ *
24
+ * const render = await createInertiaApp({
25
+ * resolve: (name) => resolvePageComponent(name),
26
+ * })
27
+ *
28
+ * const renderPage = (page) => render(page, renderToString)
29
+ *
30
+ * // Only start server in production
31
+ * if (import.meta.env.PROD) {
32
+ * createServer(renderPage)
33
+ * }
34
+ *
35
+ * export default renderPage
36
+ * ```
37
+ */
38
+ import type { FrameworkConfig } from '../types';
39
+ export declare const config: FrameworkConfig;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Inertia.js Vite Plugin
3
+ *
4
+ * This plugin provides two main features:
5
+ *
6
+ * 1. **Pages shorthand** - Transforms `pages: './Pages'` into a full `resolve` function
7
+ * that uses `import.meta.glob` to load page components. This saves users from writing
8
+ * boilerplate glob code in every project.
9
+ *
10
+ * 2. **SSR dev server** - During development, wraps the SSR entry file with server bootstrap
11
+ * code and exposes an HTTP endpoint that Laravel can call to render pages server-side.
12
+ * This eliminates the need to run a separate Node.js SSR server during development.
13
+ *
14
+ * The plugin is framework-agnostic - it detects which Inertia adapter (Vue, React, Svelte)
15
+ * is being used by looking at import statements, then applies the appropriate transforms.
16
+ * Custom frameworks can be added via the `frameworks` option.
17
+ */
18
+ import type { Plugin } from 'vite';
19
+ import { InertiaSSROptions } from './ssr';
20
+ import type { FrameworkConfig } from './types';
21
+ export type { FrameworkConfig, SSRTemplate } from './types';
22
+ export { InertiaSSROptions };
23
+ export interface InertiaPluginOptions {
24
+ /**
25
+ * SSR configuration. Pass a string for the entry path, an object for
26
+ * additional options, or `false` to disable SSR entirely. Auto-detected
27
+ * when not specified from:
28
+ * - resources/js/ssr.{ts,tsx,js,jsx}
29
+ * - src/ssr.{ts,tsx,js,jsx}
30
+ * - resources/js/app.{ts,tsx,js,jsx}
31
+ * - src/app.{ts,tsx,js,jsx}
32
+ */
33
+ ssr?: string | false | InertiaSSROptions;
34
+ /**
35
+ * Custom framework configurations. Use this to add support for frameworks
36
+ * beyond the built-in Vue, React, and Svelte adapters.
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * inertia({
41
+ * frameworks: {
42
+ * package: '@inertiajs/solid',
43
+ * extensions: ['.tsx', '.jsx'],
44
+ * extractDefault: true,
45
+ * ssr: (configureCall, options) => `
46
+ * import createServer from '@inertiajs/solid/server'
47
+ * const render = await ${configureCall}
48
+ * createServer((page) => render(page)${options})
49
+ * `,
50
+ * }
51
+ * })
52
+ * ```
53
+ */
54
+ frameworks?: FrameworkConfig | FrameworkConfig[];
55
+ }
56
+ export default function inertia(options?: InertiaPluginOptions): Plugin;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Pages Transform
3
+ *
4
+ * This module transforms the `pages` shorthand into a full `resolve` function.
5
+ * Instead of writing verbose glob code in every project, users can simply write:
6
+ *
7
+ * ```js
8
+ * createInertiaApp({ pages: './Pages' })
9
+ * ```
10
+ *
11
+ * Which gets transformed into:
12
+ *
13
+ * ```js
14
+ * createInertiaApp({
15
+ * resolve: async (name, page) => {
16
+ * const pages = import.meta.glob('./Pages/*.vue')
17
+ * const module = await (pages[`./Pages/${name}.vue`])?.()
18
+ * if (!module) throw new Error(`Page not found: ${name}`)
19
+ * return module.default ?? module
20
+ * }
21
+ * })
22
+ * ```
23
+ *
24
+ * The transform also supports advanced configuration:
25
+ *
26
+ * ```js
27
+ * createInertiaApp({
28
+ * pages: {
29
+ * path: './Pages',
30
+ * extension: '.tsx',
31
+ * lazy: true,
32
+ * transform: (name, page) => name.replace('/', '-')
33
+ * }
34
+ * })
35
+ * ```
36
+ */
37
+ import type { FrameworkConfig } from './types';
38
+ /** Returns the transformed code, or null if no transformation was needed. */
39
+ export declare function transformPageResolution(code: string, frameworks: Record<string, FrameworkConfig>): string | null;
package/types/ssr.d.ts ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * SSR Dev Server
3
+ *
4
+ * This module handles SSR rendering during development. Instead of running
5
+ * a separate Node.js SSR server, the Vite dev server exposes an HTTP endpoint
6
+ * that Laravel can call to render pages server-side.
7
+ *
8
+ * How it works:
9
+ * 1. Laravel detects that the Vite dev server is running
10
+ * 2. Laravel POSTs the page data to `/__inertia_ssr`
11
+ * 3. This module loads the SSR entry file via Vite's SSR module loader
12
+ * 4. The entry file's default export is called with the page data
13
+ * 5. The rendered HTML is returned to Laravel
14
+ *
15
+ * This approach provides:
16
+ * - Hot Module Replacement (HMR) for SSR code during development
17
+ * - No need to restart a separate SSR server when code changes
18
+ * - Automatic TypeScript/JSX transformation via Vite
19
+ */
20
+ import type { IncomingMessage, ServerResponse } from 'node:http';
21
+ import type { ResolvedConfig, ViteDevServer } from 'vite';
22
+ /** Options for the SSR dev server and production builds. */
23
+ export interface InertiaSSROptions {
24
+ /**
25
+ * Path to the SSR entry file. Auto-detected when not specified.
26
+ */
27
+ entry?: string;
28
+ /**
29
+ * Port number for the SSR server (used in production builds).
30
+ */
31
+ port?: number;
32
+ /**
33
+ * Enable cluster mode for the SSR server (used in production builds).
34
+ */
35
+ cluster?: boolean;
36
+ /**
37
+ * When enabled, SSR errors are formatted with hints instead of thrown raw.
38
+ * Defaults to true.
39
+ */
40
+ handleErrors?: boolean;
41
+ /**
42
+ * Enable sourcemaps for SSR builds so error stacks map to original files.
43
+ * Defaults to true.
44
+ */
45
+ sourcemap?: boolean;
46
+ }
47
+ export declare const SSR_ENDPOINT = "/__inertia_ssr";
48
+ export declare const SSR_ENTRY_CANDIDATES: string[];
49
+ export declare function resolveSSREntry(options: InertiaSSROptions, config: ResolvedConfig): string | null;
50
+ export declare function handleSSRRequest(server: ViteDevServer, entry: string, req: IncomingMessage, res: ServerResponse, handleErrors?: boolean): Promise<void>;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * SSR Transform
3
+ *
4
+ * Transforms the SSR entry file by wrapping `createInertiaApp()` with
5
+ * framework-specific server bootstrap code, so users don't need to
6
+ * write the boilerplate manually.
7
+ */
8
+ import type { FrameworkConfig, SSROptions } from './types';
9
+ /**
10
+ * Quick check for a top-level call that needs SSR wrapping.
11
+ */
12
+ export declare function findInertiaAppExport(code: string): boolean;
13
+ /**
14
+ * Wrap `createInertiaApp()` or `createServer()` with the framework's SSR bootstrap.
15
+ */
16
+ export declare function wrapWithServerBootstrap(code: string, options: SSROptions, frameworks: Record<string, FrameworkConfig>): string | null;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Shared Type Definitions
3
+ *
4
+ * This module contains types used across the Vite plugin for framework
5
+ * configuration and SSR options.
6
+ */
7
+ /**
8
+ * A function that generates SSR bootstrap code for a framework.
9
+ *
10
+ * The function receives the original `createInertiaApp(...)` call as a string
11
+ * and should return code that wraps it with server bootstrap logic.
12
+ *
13
+ * The generated code uses `import.meta.env.PROD` to detect dev vs production:
14
+ * - In dev: `import.meta.env.PROD` is false, so createServer is skipped
15
+ * - In production: `import.meta.env.PROD` is true, so createServer runs
16
+ *
17
+ * @param configureCall - The original createInertiaApp(...) call, e.g., `createInertiaApp({ resolve: ... })`
18
+ * @param options - Formatted SSR options string, e.g., `, {"port":13715}` or empty string
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const template: SSRTemplate = (configureCall, options) => `
23
+ * import createServer from '@inertiajs/vue3/server'
24
+ * import { renderToString } from 'vue/server-renderer'
25
+ *
26
+ * const render = await ${configureCall}
27
+ * const renderPage = (page) => render(page, renderToString)
28
+ *
29
+ * if (import.meta.env.PROD) {
30
+ * createServer(renderPage${options})
31
+ * }
32
+ *
33
+ * export default renderPage
34
+ * `
35
+ * ```
36
+ */
37
+ export type SSRTemplate = (configureCall: string, options: string) => string;
38
+ /**
39
+ * Configuration for a framework adapter.
40
+ *
41
+ * This defines how the Vite plugin should handle page resolution and SSR
42
+ * for a specific framework (Vue, React, Svelte, or custom).
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * const solidConfig: FrameworkConfig = {
47
+ * package: '@inertiajs/solid',
48
+ * extensions: ['.tsx', '.jsx'],
49
+ * extractDefault: true,
50
+ * ssr: (configureCall, options) => `...`
51
+ * }
52
+ * ```
53
+ */
54
+ export interface FrameworkConfig {
55
+ /**
56
+ * The npm package name that identifies this framework.
57
+ * The plugin detects the framework by looking for imports from this package.
58
+ *
59
+ * Examples: '@inertiajs/vue3', '@inertiajs/react', '@inertiajs/svelte'
60
+ */
61
+ package: string;
62
+ /**
63
+ * File extensions for page components.
64
+ * Used when building the import.meta.glob pattern.
65
+ *
66
+ * Examples:
67
+ * - Vue: ['.vue']
68
+ * - React: ['.tsx', '.jsx']
69
+ * - Svelte: ['.svelte']
70
+ */
71
+ extensions: string[];
72
+ /**
73
+ * Whether to extract the default export from page modules.
74
+ *
75
+ * - `true` (default): Return `module.default ?? module` - used by Vue and React
76
+ * where components are typically exported as `export default`
77
+ * - `false`: Return `module` directly - used by Svelte where the component
78
+ * is the module itself
79
+ */
80
+ extractDefault?: boolean;
81
+ /**
82
+ * SSR template function for generating server bootstrap code.
83
+ * If not provided, SSR transform will be skipped for this framework.
84
+ */
85
+ ssr?: SSRTemplate;
86
+ }
87
+ /**
88
+ * Options passed to the SSR server bootstrap code.
89
+ */
90
+ export interface SSROptions {
91
+ /**
92
+ * Port number for the SSR server.
93
+ * Used in production when running the SSR server as a separate process.
94
+ */
95
+ port?: number;
96
+ /**
97
+ * Whether to enable cluster mode for the SSR server.
98
+ * Cluster mode spawns multiple worker processes for better performance.
99
+ */
100
+ cluster?: boolean;
101
+ /**
102
+ * Handle SSR errors gracefully with formatted output and helpful hints.
103
+ * When disabled, errors are thrown raw for debugging.
104
+ * Defaults to true.
105
+ */
106
+ handleErrors?: boolean;
107
+ }