nitro-nightly 3.0.1-alpha.2 → 3.0.260415-beta

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.
Files changed (297) hide show
  1. package/LICENSE +6 -0
  2. package/README.md +2 -2
  3. package/dist/THIRD-PARTY-LICENSES.md +1646 -0
  4. package/dist/_build/common.mjs +7259 -3815
  5. package/dist/_build/rolldown.mjs +32 -42
  6. package/dist/_build/rollup.mjs +28 -48
  7. package/dist/_build/vite.build.mjs +10 -10
  8. package/dist/_chunks/nitro.mjs +102 -327
  9. package/dist/_chunks/nitro2.mjs +8 -9
  10. package/dist/_chunks/nitro3.mjs +136 -0
  11. package/dist/_chunks/nitro4.mjs +127 -0
  12. package/dist/_chunks/utils.mjs +40 -29
  13. package/dist/_common.mjs +13 -25
  14. package/dist/_dev.d.mts +0 -3
  15. package/dist/{_chunks/dev.mjs → _dev.mjs} +132 -330
  16. package/dist/_libs/_.mjs +2 -0
  17. package/dist/_libs/_2.mjs +2 -0
  18. package/dist/_libs/_3.mjs +2 -0
  19. package/dist/_libs/_4.mjs +2 -0
  20. package/dist/_libs/_5.mjs +2 -0
  21. package/dist/_libs/_6.mjs +2 -0
  22. package/dist/_libs/_7.mjs +2 -0
  23. package/dist/_libs/c12+rc9.mjs +814 -0
  24. package/dist/_libs/{c12+giget+readdirp+chokidar.d.mts → c12+readdirp+chokidar.d.mts} +49 -40
  25. package/dist/_libs/citty.mjs +142 -41
  26. package/dist/_libs/commondir+is-reference.mjs +60 -56
  27. package/dist/_libs/compatx.d.mts +0 -2
  28. package/dist/_libs/compatx.mjs +1 -4
  29. package/dist/_libs/esbuild.d.mts +0 -1
  30. package/dist/_libs/escape-string-regexp.mjs +1 -4
  31. package/dist/_libs/{pluginutils+plugin-commonjs.d.mts → estree+pluginutils.d.mts} +0 -5
  32. package/dist/_libs/estree-walker.mjs +4 -92
  33. package/dist/_libs/exsolve.d.mts +1 -0
  34. package/dist/_libs/hasown+resolve+deepmerge.mjs +160 -246
  35. package/dist/_libs/httpxy.d.mts +20 -13
  36. package/dist/_libs/httpxy.mjs +519 -95
  37. package/dist/_libs/js-tokens.d.mts +1 -0
  38. package/dist/_libs/klona.mjs +1 -4
  39. package/dist/_libs/magic-string.d.mts +0 -2
  40. package/dist/_libs/mlly.d.mts +0 -2
  41. package/dist/_libs/nypm+tinyexec.mjs +822 -0
  42. package/dist/_libs/perfect-debounce.mjs +68 -0
  43. package/dist/_libs/pkg-types.d.mts +0 -3
  44. package/dist/_libs/plugin-alias.mjs +1 -5
  45. package/dist/_libs/plugin-inject.mjs +1 -7
  46. package/dist/_libs/plugin-json.mjs +1 -5
  47. package/dist/_libs/pluginutils.mjs +3 -35
  48. package/dist/_libs/readdirp+chokidar.mjs +187 -365
  49. package/dist/_libs/remapping.mjs +1 -5
  50. package/dist/_libs/resolve-uri+gen-mapping.mjs +15 -53
  51. package/dist/_libs/rou3.d.mts +1 -4
  52. package/dist/_libs/rou3.mjs +223 -78
  53. package/dist/_libs/std-env.d.mts +8 -2
  54. package/dist/_libs/strip-literal.d.mts +1 -0
  55. package/dist/_libs/tsconfck.mjs +21 -334
  56. package/dist/_libs/ultrahtml.mjs +3 -16
  57. package/dist/_libs/unimport+unplugin.mjs +244 -388
  58. package/dist/_libs/unplugin+unimport.d.mts +5 -15
  59. package/dist/_libs/unwasm.d.mts +0 -3
  60. package/dist/_presets.mjs +575 -488
  61. package/dist/builder.d.mts +5 -25
  62. package/dist/builder.mjs +3 -8
  63. package/dist/cli/_chunks/build.mjs +22 -25
  64. package/dist/cli/_chunks/common.mjs +1 -4
  65. package/dist/cli/_chunks/deploy.mjs +37 -0
  66. package/dist/cli/_chunks/dev.mjs +6 -11
  67. package/dist/cli/_chunks/docs.mjs +28 -0
  68. package/dist/cli/_chunks/list.mjs +4 -8
  69. package/dist/cli/_chunks/prepare.mjs +2 -6
  70. package/dist/cli/_chunks/preview.mjs +48 -0
  71. package/dist/cli/_chunks/run.mjs +7 -11
  72. package/dist/cli/_chunks/task.mjs +1 -5
  73. package/dist/cli/index.mjs +5 -6
  74. package/dist/docs/0.docs/0.index/index.md +56 -0
  75. package/dist/docs/0.docs/1.quick-start.md +110 -0
  76. package/dist/docs/0.docs/10.lifecycle.md +204 -0
  77. package/dist/docs/0.docs/11.openapi.md +291 -0
  78. package/dist/docs/0.docs/12.plugins.md +164 -0
  79. package/dist/docs/0.docs/13.tasks.md +277 -0
  80. package/dist/docs/0.docs/14.websocket.md +386 -0
  81. package/dist/docs/0.docs/15.migration.md +213 -0
  82. package/dist/docs/0.docs/16.nightly.md +31 -0
  83. package/dist/docs/0.docs/2.renderer.md +322 -0
  84. package/dist/docs/0.docs/3.routing.md +711 -0
  85. package/dist/docs/0.docs/4.server-entry.md +239 -0
  86. package/dist/docs/0.docs/5.cache.md +408 -0
  87. package/dist/docs/0.docs/6.storage.md +261 -0
  88. package/dist/docs/0.docs/7.assets.md +166 -0
  89. package/dist/docs/0.docs/8.configuration.md +256 -0
  90. package/dist/docs/0.docs/9.database.md +185 -0
  91. package/dist/docs/1.deploy/0.index/index.md +64 -0
  92. package/dist/docs/1.deploy/1.runtimes/0.node.md +63 -0
  93. package/dist/docs/1.deploy/1.runtimes/1.bun.md +15 -0
  94. package/dist/docs/1.deploy/1.runtimes/2.deno.md +19 -0
  95. package/dist/docs/1.deploy/2.providers/0.alwaysdata.md +50 -0
  96. package/dist/docs/1.deploy/2.providers/1.aws.md +47 -0
  97. package/dist/docs/1.deploy/2.providers/10.flightcontrol.md +67 -0
  98. package/dist/docs/1.deploy/2.providers/11.genezio.md +67 -0
  99. package/dist/docs/1.deploy/2.providers/12.github-pages.md +68 -0
  100. package/dist/docs/1.deploy/2.providers/13.gitlab-pages.md +37 -0
  101. package/dist/docs/1.deploy/2.providers/14.heroku.md +84 -0
  102. package/dist/docs/1.deploy/2.providers/15.iis.md +38 -0
  103. package/dist/docs/1.deploy/2.providers/16.koyeb.md +109 -0
  104. package/dist/docs/1.deploy/2.providers/17.netlify.md +47 -0
  105. package/dist/docs/1.deploy/2.providers/18.platform-sh.md +37 -0
  106. package/dist/docs/1.deploy/2.providers/19.render.md +37 -0
  107. package/dist/docs/1.deploy/2.providers/2.aws-amplify.md +81 -0
  108. package/dist/docs/1.deploy/2.providers/20.stormkit.md +24 -0
  109. package/dist/docs/1.deploy/2.providers/21.vercel.md +270 -0
  110. package/dist/docs/1.deploy/2.providers/22.zeabur.md +19 -0
  111. package/dist/docs/1.deploy/2.providers/23.zephyr.md +99 -0
  112. package/dist/docs/1.deploy/2.providers/24.zerops.md +102 -0
  113. package/dist/docs/1.deploy/2.providers/3.azure.md +72 -0
  114. package/dist/docs/1.deploy/2.providers/4.cleavr.md +33 -0
  115. package/dist/docs/1.deploy/2.providers/5.cloudflare.md +369 -0
  116. package/dist/docs/1.deploy/2.providers/6.deno-deploy.md +66 -0
  117. package/dist/docs/1.deploy/2.providers/7.digitalocean.md +46 -0
  118. package/dist/docs/1.deploy/2.providers/8.edgeone.md +20 -0
  119. package/dist/docs/1.deploy/2.providers/9.firebase.md +32 -0
  120. package/dist/docs/2.config/0.index/index.md +1221 -0
  121. package/dist/docs/3.examples/0.index/index.md +3 -0
  122. package/dist/docs/3.examples/1.api-routes.md +145 -0
  123. package/dist/docs/3.examples/10.hono.md +74 -0
  124. package/dist/docs/3.examples/11.import-alias.md +97 -0
  125. package/dist/docs/3.examples/12.middleware.md +91 -0
  126. package/dist/docs/3.examples/13.mono-jsx.md +68 -0
  127. package/dist/docs/3.examples/14.nano-jsx.md +70 -0
  128. package/dist/docs/3.examples/15.plugins.md +91 -0
  129. package/dist/docs/3.examples/16.renderer.md +113 -0
  130. package/dist/docs/3.examples/17.runtime-config.md +97 -0
  131. package/dist/docs/3.examples/18.server-fetch.md +87 -0
  132. package/dist/docs/3.examples/19.shiki.md +198 -0
  133. package/dist/docs/3.examples/2.auto-imports.md +92 -0
  134. package/dist/docs/3.examples/20.virtual-routes.md +74 -0
  135. package/dist/docs/3.examples/21.vite-nitro-plugin.md +79 -0
  136. package/dist/docs/3.examples/22.vite-rsc.md +1041 -0
  137. package/dist/docs/3.examples/23.vite-ssr-html.md +217 -0
  138. package/dist/docs/3.examples/24.vite-ssr-preact.md +247 -0
  139. package/dist/docs/3.examples/25.vite-ssr-react.md +226 -0
  140. package/dist/docs/3.examples/26.vite-ssr-solid.md +256 -0
  141. package/dist/docs/3.examples/27.vite-ssr-tsr-react.md +442 -0
  142. package/dist/docs/3.examples/28.vite-ssr-tss-react.md +444 -0
  143. package/dist/docs/3.examples/29.vite-ssr-vue-router.md +617 -0
  144. package/dist/docs/3.examples/3.cached-handler.md +81 -0
  145. package/dist/docs/3.examples/30.vite-trpc.md +335 -0
  146. package/dist/docs/3.examples/31.websocket.md +282 -0
  147. package/dist/docs/3.examples/4.custom-error-handler.md +98 -0
  148. package/dist/docs/3.examples/5.database.md +157 -0
  149. package/dist/docs/3.examples/6.elysia.md +70 -0
  150. package/dist/docs/3.examples/7.express.md +78 -0
  151. package/dist/docs/3.examples/8.fastify.md +79 -0
  152. package/dist/docs/3.examples/9.hello-world.md +68 -0
  153. package/dist/docs/README.md +86 -0
  154. package/dist/docs/index.md +121 -0
  155. package/dist/node_modules/@poppinss/dumper/build/formatters/html/main.js +8 -0
  156. package/dist/node_modules/@poppinss/dumper/package.json +1 -1
  157. package/dist/node_modules/@speed-highlight/core/dist/index.js +4 -4
  158. package/dist/node_modules/@speed-highlight/core/dist/terminal.js +2 -2
  159. package/dist/node_modules/@speed-highlight/core/package.json +1 -1
  160. package/dist/node_modules/cookie-es/dist/index.mjs +299 -250
  161. package/dist/node_modules/cookie-es/package.json +26 -23
  162. package/dist/node_modules/croner/dist/croner.js +1 -1
  163. package/dist/node_modules/croner/package.json +11 -1
  164. package/dist/node_modules/defu/dist/defu.mjs +2 -2
  165. package/dist/node_modules/defu/package.json +33 -28
  166. package/dist/node_modules/rendu/dist/_chunks/libs/cookie-es.mjs +151 -0
  167. package/dist/node_modules/rendu/dist/index.mjs +5 -112
  168. package/dist/node_modules/rendu/package.json +25 -24
  169. package/dist/node_modules/youch/build/helpers-B9BQYaS6.js +23 -0
  170. package/dist/node_modules/youch/build/index.js +204 -351
  171. package/dist/node_modules/youch/build/public/error_info/script.js +1 -1
  172. package/dist/node_modules/youch/build/public_dir-C5bujZKB.js +25 -0
  173. package/dist/node_modules/youch/build/src/templates/error_cause/main.js +44 -0
  174. package/dist/node_modules/youch/build/src/templates/error_info/main.js +72 -0
  175. package/dist/node_modules/youch/build/src/templates/error_metadata/main.js +65 -0
  176. package/dist/node_modules/youch/build/src/templates/error_stack/main.js +152 -0
  177. package/dist/node_modules/youch/build/src/templates/error_stack_source/main.js +46 -0
  178. package/dist/node_modules/youch/build/src/templates/header/main.js +24 -0
  179. package/dist/node_modules/youch/build/src/templates/layout/main.js +27 -0
  180. package/dist/node_modules/youch/package.json +35 -32
  181. package/dist/presets/_nitro/runtime/nitro-dev.mjs +12 -57
  182. package/dist/presets/_nitro/runtime/nitro-prerenderer.mjs +1 -0
  183. package/dist/presets/_nitro/runtime/service-worker.mjs +1 -2
  184. package/dist/presets/aws-lambda/runtime/_utils.mjs +6 -6
  185. package/dist/presets/aws-lambda/runtime/aws-lambda-streaming.mjs +3 -1
  186. package/dist/presets/azure/runtime/_utils.mjs +5 -5
  187. package/dist/presets/azure/runtime/azure-swa.mjs +5 -5
  188. package/dist/presets/bun/runtime/bun.mjs +9 -6
  189. package/dist/presets/cloudflare/runtime/_module-handler.mjs +1 -1
  190. package/dist/presets/cloudflare/runtime/cloudflare-durable.mjs +4 -4
  191. package/dist/presets/cloudflare/runtime/cloudflare-module.mjs +3 -3
  192. package/dist/presets/cloudflare/runtime/cloudflare-pages.mjs +2 -2
  193. package/dist/presets/cloudflare/runtime/plugin.dev.mjs +10 -21
  194. package/dist/presets/deno/runtime/deno-deploy.mjs +4 -4
  195. package/dist/presets/deno/runtime/deno-server.mjs +9 -6
  196. package/dist/presets/edgeone/runtime/edgeone.mjs +10 -0
  197. package/dist/presets/netlify/runtime/netlify-edge.mjs +2 -3
  198. package/dist/presets/netlify/runtime/netlify.mjs +1 -1
  199. package/dist/presets/node/runtime/node-cluster.mjs +5 -4
  200. package/dist/presets/node/runtime/node-middleware.mjs +1 -1
  201. package/dist/presets/node/runtime/node-server.mjs +8 -5
  202. package/dist/presets/stormkit/runtime/stormkit.mjs +1 -2
  203. package/dist/presets/vercel/runtime/cron-handler.mjs +25 -0
  204. package/dist/presets/vercel/runtime/queue-handler.mjs +21 -0
  205. package/dist/presets/vercel/runtime/vercel.node.mjs +3 -3
  206. package/dist/presets/vercel/runtime/vercel.web.mjs +3 -5
  207. package/dist/presets/winterjs/runtime/winterjs.mjs +10 -10
  208. package/dist/presets/zephyr/runtime/server.mjs +3 -0
  209. package/dist/runtime/internal/app.mjs +12 -11
  210. package/dist/runtime/internal/cache.d.mts +0 -4
  211. package/dist/runtime/internal/cache.mjs +32 -256
  212. package/dist/runtime/internal/context.d.mts +3 -1
  213. package/dist/runtime/internal/context.mjs +1 -9
  214. package/dist/runtime/internal/error/dev.d.mts +5 -4
  215. package/dist/runtime/internal/error/dev.mjs +47 -49
  216. package/dist/runtime/internal/error/hooks.d.mts +1 -1
  217. package/dist/runtime/internal/error/prod.d.mts +2 -5
  218. package/dist/runtime/internal/error/prod.mjs +19 -33
  219. package/dist/runtime/internal/error/utils.d.mts +4 -4
  220. package/dist/runtime/internal/meta.d.mts +1 -1
  221. package/dist/runtime/internal/plugin.d.mts +2 -2
  222. package/dist/runtime/internal/route-rules.d.mts +11 -4
  223. package/dist/runtime/internal/route-rules.mjs +15 -5
  224. package/dist/runtime/internal/routes/dev-tasks.d.mts +3 -2
  225. package/dist/runtime/internal/routes/dev-tasks.mjs +15 -10
  226. package/dist/runtime/internal/routes/openapi.mjs +2 -2
  227. package/dist/runtime/internal/routes/renderer-template.d.mts +1 -1
  228. package/dist/runtime/internal/routes/renderer-template.dev.d.mts +2 -1
  229. package/dist/runtime/internal/routes/scalar.mjs +3 -3
  230. package/dist/runtime/internal/routes/swagger.mjs +7 -4
  231. package/dist/runtime/internal/runtime-config.d.mts +1 -1
  232. package/dist/runtime/internal/runtime-config.mjs +2 -2
  233. package/dist/runtime/internal/static.mjs +5 -4
  234. package/dist/runtime/internal/task.d.mts +3 -1
  235. package/dist/runtime/internal/task.mjs +7 -7
  236. package/dist/runtime/internal/vite/dev-entry.mjs +6 -3
  237. package/dist/runtime/internal/vite/dev-worker.mjs +264 -0
  238. package/dist/runtime/meta.d.mts +1 -0
  239. package/dist/runtime/meta.mjs +2 -0
  240. package/dist/runtime/nitro.d.mts +2 -0
  241. package/dist/runtime/nitro.mjs +4 -2
  242. package/dist/runtime/virtual/error-handler.mjs +1 -1
  243. package/dist/runtime/virtual/renderer-template.mjs +1 -1
  244. package/dist/runtime/virtual/server-assets.d.mts +2 -1
  245. package/dist/runtime/virtual/tracing.d.mts +5 -0
  246. package/dist/runtime/virtual/tracing.mjs +1 -0
  247. package/dist/runtime/vite.d.mts +1 -1
  248. package/dist/types/index.d.mts +215 -195
  249. package/dist/types/index.mjs +1 -11
  250. package/dist/vite.d.mts +3 -8
  251. package/dist/vite.mjs +285 -253
  252. package/lib/tsconfig.json +3 -5
  253. package/package.json +97 -80
  254. package/dist/_libs/confbox.mjs +0 -2509
  255. package/dist/_libs/nypm+giget+tinyexec.mjs +0 -3603
  256. package/dist/_libs/rc9+c12+dotenv.mjs +0 -972
  257. package/dist/node_modules/hookable/dist/index.mjs +0 -266
  258. package/dist/node_modules/hookable/package.json +0 -52
  259. package/dist/node_modules/youch/build/chunk-4L7RY2JA.js +0 -42
  260. package/dist/node_modules/youch/build/chunk-7QV3D5YX.js +0 -83
  261. package/dist/node_modules/youch/build/chunk-AUGPHE32.js +0 -39
  262. package/dist/node_modules/youch/build/chunk-CM7DWJNZ.js +0 -44
  263. package/dist/node_modules/youch/build/chunk-EJH674NB.js +0 -223
  264. package/dist/node_modules/youch/build/chunk-OIJ3WD7L.js +0 -81
  265. package/dist/node_modules/youch/build/chunk-P36L72PL.js +0 -87
  266. package/dist/node_modules/youch/build/chunk-PE3GG3TN.js +0 -65
  267. package/dist/node_modules/youch/build/chunk-X53OIOJH.js +0 -70
  268. package/dist/presets/_nitro/runtime/nitro-dev.d.mts +0 -2
  269. package/dist/presets/_nitro/runtime/nitro-prerenderer.d.mts +0 -3
  270. package/dist/presets/_nitro/runtime/service-worker.d.mts +0 -2
  271. package/dist/presets/aws-amplify/runtime/aws-amplify.d.mts +0 -2
  272. package/dist/presets/aws-lambda/runtime/_utils.d.mts +0 -8
  273. package/dist/presets/aws-lambda/runtime/aws-lambda-streaming.d.mts +0 -2
  274. package/dist/presets/aws-lambda/runtime/aws-lambda.d.mts +0 -3
  275. package/dist/presets/azure/runtime/_utils.d.mts +0 -2
  276. package/dist/presets/azure/runtime/azure-swa.d.mts +0 -5
  277. package/dist/presets/bun/runtime/bun.d.mts +0 -3
  278. package/dist/presets/cloudflare/runtime/_module-handler.d.mts +0 -16
  279. package/dist/presets/cloudflare/runtime/cloudflare-durable.d.mts +0 -11
  280. package/dist/presets/cloudflare/runtime/cloudflare-module.d.mts +0 -3
  281. package/dist/presets/cloudflare/runtime/cloudflare-pages.d.mts +0 -20
  282. package/dist/presets/cloudflare/runtime/plugin.dev.d.mts +0 -3
  283. package/dist/presets/deno/runtime/deno-deploy.d.mts +0 -5
  284. package/dist/presets/deno/runtime/deno-server.d.mts +0 -3
  285. package/dist/presets/netlify/runtime/netlify-edge.d.mts +0 -3
  286. package/dist/presets/netlify/runtime/netlify.d.mts +0 -4
  287. package/dist/presets/node/runtime/node-cluster.d.mts +0 -3
  288. package/dist/presets/node/runtime/node-middleware.d.mts +0 -3
  289. package/dist/presets/node/runtime/node-server.d.mts +0 -3
  290. package/dist/presets/standard/runtime/server.d.mts +0 -3
  291. package/dist/presets/stormkit/runtime/stormkit.d.mts +0 -21
  292. package/dist/presets/vercel/runtime/isr.d.mts +0 -2
  293. package/dist/presets/vercel/runtime/vercel.node.d.mts +0 -3
  294. package/dist/presets/vercel/runtime/vercel.web.d.mts +0 -8
  295. package/dist/presets/winterjs/runtime/winterjs.d.mts +0 -2
  296. package/dist/presets/zeabur/runtime/zeabur.d.mts +0 -3
  297. package/dist/runtime/internal/vite/node-runner.mjs +0 -359
@@ -0,0 +1,217 @@
1
+ # Vite SSR HTML
2
+
3
+ > Server-side rendering with vanilla HTML, Vite, and Nitro.
4
+
5
+ <code-tree>
6
+
7
+ ```html [index.html]
8
+ <!doctype html>
9
+ <html lang="en">
10
+ <head>
11
+ <meta charset="UTF-8" />
12
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
13
+ <title>Nitro Quotes</title>
14
+ <style>
15
+ @import "tailwindcss";
16
+ </style>
17
+ </head>
18
+ <body
19
+ class="min-h-screen flex items-center justify-center p-5 bg-gradient-to-br from-indigo-500 to-purple-600 font-sans"
20
+ >
21
+ <div class="max-w-xl w-full text-center text-white">
22
+ <div class="bg-white/10 backdrop-blur-md rounded-2xl p-10 shadow-xl border border-white/20">
23
+ <div
24
+ id="quote"
25
+ class="text-[clamp(1.2rem,4vw,1.8rem)] leading-relaxed mb-5 font-light opacity-70 transition-opacity duration-500"
26
+ >
27
+ <!--ssr-outlet-->
28
+ </div>
29
+ <div
30
+ id="author"
31
+ class="text-[clamp(1rem,3vw,1.2rem)] opacity-0 font-normal transition-opacity duration-500"
32
+ ></div>
33
+ <button
34
+ id="refresh-btn"
35
+ class="mt-5 bg-white/20 border border-white/30 text-white px-6 py-3 rounded-full cursor-pointer text-sm transition hover:bg-white/30 hover:-translate-y-0.5"
36
+ onclick="fetchQuote()"
37
+ >
38
+ New Quote
39
+ </button>
40
+ </div>
41
+ <div class="mt-8 text-sm opacity-60">
42
+ Powered by
43
+ <a
44
+ class="text-white no-underline border-b border-white/30 hover:border-white transition-colors"
45
+ href="https://vitejs.dev/"
46
+ >Vite</a
47
+ >
48
+ and
49
+ <a
50
+ class="text-white no-underline border-b border-white/30 hover:border-white transition-colors"
51
+ href="https://github.com/nitrojs/nitro"
52
+ >Nitro v3</a
53
+ >.
54
+ </div>
55
+ </div>
56
+
57
+ <script>
58
+ const quoteElement = document.getElementById("quote");
59
+ const authorElement = document.getElementById("author");
60
+ const refreshBtn = document.getElementById("refresh-btn");
61
+
62
+ const baseQuoteClasses =
63
+ "text-[clamp(1.2rem,4vw,1.8rem)] leading-relaxed mb-5 font-light transition-opacity duration-500";
64
+ const loadingQuoteClasses = baseQuoteClasses + " opacity-70";
65
+ const normalQuoteClasses = baseQuoteClasses + " opacity-100";
66
+ const errorQuoteClasses = baseQuoteClasses + " text-red-400 opacity-100 text-sm";
67
+
68
+ const baseAuthorClasses =
69
+ "text-[clamp(1rem,3vw,1.2rem)] font-normal transition-opacity duration-500";
70
+ const hiddenAuthorClasses = baseAuthorClasses + " opacity-0";
71
+ const visibleAuthorClasses = baseAuthorClasses + " opacity-80";
72
+
73
+ async function fetchQuote() {
74
+ try {
75
+ quoteElement.textContent = "Loading...";
76
+ quoteElement.className = loadingQuoteClasses;
77
+ authorElement.textContent = "";
78
+ authorElement.className = hiddenAuthorClasses;
79
+ refreshBtn.style.display = "none";
80
+ const response = await fetch("/quote");
81
+ if (!response.ok) {
82
+ throw new Error(`HTTP error! status: ${response.status}`);
83
+ }
84
+ const { text, author } = await response.json();
85
+ quoteElement.textContent = `"${text}"`;
86
+ quoteElement.className = normalQuoteClasses;
87
+ authorElement.textContent = `— ${author}`;
88
+ authorElement.className = visibleAuthorClasses;
89
+ } catch (error) {
90
+ console.error("Error fetching quote:", error);
91
+ quoteElement.textContent = "Failed to load quote. Please try again.";
92
+ quoteElement.className = errorQuoteClasses;
93
+ authorElement.textContent = "";
94
+ authorElement.className = hiddenAuthorClasses;
95
+ } finally {
96
+ refreshBtn.style.display = "inline-block";
97
+ }
98
+ }
99
+ </script>
100
+ </body>
101
+ </html>
102
+ ```
103
+
104
+ ```json [package.json]
105
+ {
106
+ "type": "module",
107
+ "scripts": {
108
+ "build": "vite build",
109
+ "dev": "vite dev",
110
+ "preview": "vite preview"
111
+ },
112
+ "devDependencies": {
113
+ "@tailwindcss/vite": "^4.2.2",
114
+ "nitro": "latest",
115
+ "tailwindcss": "^4.2.2",
116
+ "vite": "latest"
117
+ }
118
+ }
119
+ ```
120
+
121
+ ```json [tsconfig.json]
122
+ {
123
+ "extends": "nitro/tsconfig"
124
+ }
125
+ ```
126
+
127
+ ```ts [vite.config.ts]
128
+ import { defineConfig } from "vite";
129
+ import { nitro } from "nitro/vite";
130
+
131
+ import tailwindcss from "@tailwindcss/vite";
132
+
133
+ export default defineConfig({
134
+ plugins: [
135
+ nitro({
136
+ serverDir: "./",
137
+ }),
138
+ tailwindcss(),
139
+ ],
140
+ });
141
+ ```
142
+
143
+ ```ts [app/entry-server.ts]
144
+ import { fetch } from "nitro";
145
+
146
+ export default {
147
+ async fetch() {
148
+ const quote = (await fetch("/quote").then((res) => res.json())) as {
149
+ text: string;
150
+ };
151
+ return tokenizedStream(quote.text, 50);
152
+ },
153
+ };
154
+
155
+ function tokenizedStream(text: string, delay: number): ReadableStream<Uint8Array> {
156
+ const tokens = text.split(" ");
157
+ return new ReadableStream({
158
+ start(controller) {
159
+ let index = 0;
160
+ function push() {
161
+ if (index < tokens.length) {
162
+ const word = tokens[index++] + (index < tokens.length ? " " : "");
163
+ controller.enqueue(new TextEncoder().encode(word));
164
+ setTimeout(push, delay);
165
+ } else {
166
+ controller.close();
167
+ }
168
+ }
169
+ push();
170
+ },
171
+ });
172
+ }
173
+ ```
174
+
175
+ ```ts [routes/quote.ts]
176
+ const QUOTES_URL =
177
+ "https://github.com/JamesFT/Database-Quotes-JSON/raw/refs/heads/master/quotes.json";
178
+
179
+ let _quotes: Promise<unknown> | undefined;
180
+
181
+ function getQuotes() {
182
+ return (_quotes ??= fetch(QUOTES_URL).then((res) => res.json())) as Promise<
183
+ { quoteText: string; quoteAuthor: string }[]
184
+ >;
185
+ }
186
+
187
+ export default async function quotesHandler() {
188
+ const quotes = await getQuotes();
189
+ const randomQuote = quotes[Math.floor(Math.random() * quotes.length)];
190
+ return Response.json({
191
+ text: randomQuote.quoteText,
192
+ author: randomQuote.quoteAuthor,
193
+ });
194
+ }
195
+ ```
196
+ </code-tree>
197
+
198
+ This example renders an HTML template with server-side data and streams the response word by word. It demonstrates how to use Nitro's Vite SSR integration without a framework.
199
+
200
+ ## Overview
201
+
202
+ 1. **Add the Nitro Vite plugin** to enable SSR
203
+ 2. **Create an HTML template** with a `<!--ssr-outlet-->` comment where server content goes
204
+ 3. **Create a server entry** that fetches data and returns a stream
205
+ 4. **Add API routes** for server-side data
206
+
207
+ ## How It Works
208
+ The `index.html` file contains an `<!--ssr-outlet-->` comment that marks where server-rendered content will be inserted. Nitro replaces this comment with the output from your server entry.
209
+
210
+ The server entry exports an object with a `fetch` method. It calls the `/quote` API route using Nitro's internal fetch, then returns a `ReadableStream` that emits the quote text word by word with a 50ms delay between each word.
211
+
212
+ The quote route fetches a JSON file of quotes from GitHub, caches the result, and returns a random quote. The server entry calls this route to get content for the page.
213
+
214
+ ## Learn More
215
+
216
+ - [Renderer](/docs/renderer)
217
+ - [Server Entry](/docs/server-entry)
@@ -0,0 +1,247 @@
1
+ # SSR with Preact
2
+
3
+ > Server-side rendering with Preact in Nitro using Vite.
4
+
5
+ <code-tree>
6
+
7
+ ```json [package.json]
8
+ {
9
+ "type": "module",
10
+ "scripts": {
11
+ "build": "vite build",
12
+ "preview": "vite preview",
13
+ "dev": "vite dev"
14
+ },
15
+ "devDependencies": {
16
+ "@preact/preset-vite": "^2.10.5",
17
+ "@tailwindcss/vite": "^4.2.2",
18
+ "nitro": "latest",
19
+ "preact": "^10.29.0",
20
+ "preact-render-to-string": "^6.6.7",
21
+ "tailwindcss": "^4.2.2",
22
+ "vite": "latest"
23
+ }
24
+ }
25
+ ```
26
+
27
+ ```json [tsconfig.json]
28
+ {
29
+ "extends": "nitro/tsconfig",
30
+ "compilerOptions": {
31
+ "jsx": "react-jsx",
32
+ "jsxImportSource": "preact"
33
+ }
34
+ }
35
+ ```
36
+
37
+ ```js [vite.config.mjs]
38
+ import { defineConfig } from "vite";
39
+ import { nitro } from "nitro/vite";
40
+ import preact from "@preact/preset-vite";
41
+
42
+ export default defineConfig({
43
+ plugins: [nitro(), preact()],
44
+ environments: {
45
+ client: {
46
+ build: {
47
+ rollupOptions: {
48
+ input: "./src/entry-client.tsx",
49
+ },
50
+ },
51
+ },
52
+ },
53
+ });
54
+ ```
55
+
56
+ ```tsx [src/app.tsx]
57
+ import { useState } from "preact/hooks";
58
+
59
+ export function App() {
60
+ const [count, setCount] = useState(0);
61
+ return <button onClick={() => setCount((c) => c + 1)}>Count is {count}</button>;
62
+ }
63
+ ```
64
+
65
+ ```tsx [src/entry-client.tsx]
66
+ import { hydrate } from "preact";
67
+ import { App } from "./app.tsx";
68
+
69
+ function main() {
70
+ hydrate(<App />, document.querySelector("#app")!);
71
+ }
72
+
73
+ main();
74
+ ```
75
+
76
+ ```tsx [src/entry-server.tsx]
77
+ import "./styles.css";
78
+ import { renderToReadableStream } from "preact-render-to-string/stream";
79
+ import { App } from "./app.jsx";
80
+
81
+ import clientAssets from "./entry-client?assets=client";
82
+ import serverAssets from "./entry-server?assets=ssr";
83
+
84
+ export default {
85
+ async fetch(request: Request) {
86
+ const url = new URL(request.url);
87
+ const htmlStream = renderToReadableStream(<Root url={url} />);
88
+ return new Response(htmlStream, {
89
+ headers: { "Content-Type": "text/html;charset=utf-8" },
90
+ });
91
+ },
92
+ };
93
+
94
+ function Root(props: { url: URL }) {
95
+ const assets = clientAssets.merge(serverAssets);
96
+ return (
97
+ <html lang="en">
98
+ <head>
99
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
100
+ {assets.css.map((attr: any) => (
101
+ <link key={attr.href} rel="stylesheet" {...attr} />
102
+ ))}
103
+ {assets.js.map((attr: any) => (
104
+ <link key={attr.href} type="modulepreload" {...attr} />
105
+ ))}
106
+ <script type="module" src={assets.entry} />
107
+ </head>
108
+ <body>
109
+ <h1 className="hero">Nitro + Vite + Preact</h1>
110
+ <p>URL: {props.url.href}</p>
111
+ <div id="app">
112
+ <App />
113
+ </div>
114
+ </body>
115
+ </html>
116
+ );
117
+ }
118
+ ```
119
+
120
+ ```css [src/styles.css]
121
+ .hero {
122
+ color: orange;
123
+ }
124
+
125
+ button {
126
+ background-color: lightskyblue;
127
+ }
128
+ ```
129
+ </code-tree>
130
+
131
+ Set up server-side rendering (SSR) with Preact, Vite, and Nitro. This setup enables streaming HTML responses, automatic asset management, and client hydration.
132
+
133
+ ## Overview
134
+
135
+ 1. Add the Nitro Vite plugin to your Vite config
136
+ 2. Configure client and server entry points
137
+ 3. Create a server entry that renders your app to HTML
138
+ 4. Create a client entry that hydrates the server-rendered HTML
139
+
140
+ ## 1. Configure Vite
141
+ Add the Nitro and Preact plugins to your Vite config. Define the `client` environment with your client entry point:
142
+
143
+ ```js [vite.config.mjs]
144
+ import { defineConfig } from "vite";
145
+ import { nitro } from "nitro/vite";
146
+ import preact from "@preact/preset-vite";
147
+
148
+ export default defineConfig({
149
+ plugins: [nitro(), preact()],
150
+ environments: {
151
+ client: {
152
+ build: {
153
+ rollupOptions: {
154
+ input: "./src/entry-client.tsx",
155
+ },
156
+ },
157
+ },
158
+ },
159
+ });
160
+ ```
161
+
162
+ The `environments.client` configuration tells Vite which file to use as the browser entry point. Nitro automatically detects the server entry from files named `entry-server` or `server` in common directories.
163
+
164
+ ## 2. Create the App Component
165
+
166
+ Create a shared Preact component that runs on both server and client:
167
+
168
+ ```tsx [src/app.tsx]
169
+ import { useState } from "preact/hooks";
170
+
171
+ export function App() {
172
+ const [count, setCount] = useState(0);
173
+ return <button onClick={() => setCount((c) => c + 1)}>Count is {count}</button>;
174
+ }
175
+ ```
176
+
177
+ ## 3. Create the Server Entry
178
+
179
+ The server entry renders your Preact app to a streaming HTML response using `preact-render-to-string/stream`:
180
+
181
+ ```tsx [src/entry-server.tsx]
182
+ import "./styles.css";
183
+ import { renderToReadableStream } from "preact-render-to-string/stream";
184
+ import { App } from "./app.jsx";
185
+
186
+ import clientAssets from "./entry-client?assets=client";
187
+ import serverAssets from "./entry-server?assets=ssr";
188
+
189
+ export default {
190
+ async fetch(request: Request) {
191
+ const url = new URL(request.url);
192
+ const htmlStream = renderToReadableStream(<Root url={url} />);
193
+ return new Response(htmlStream, {
194
+ headers: { "Content-Type": "text/html;charset=utf-8" },
195
+ });
196
+ },
197
+ };
198
+
199
+ function Root(props: { url: URL }) {
200
+ const assets = clientAssets.merge(serverAssets);
201
+ return (
202
+ <html lang="en">
203
+ <head>
204
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
205
+ {assets.css.map((attr: any) => (
206
+ <link key={attr.href} rel="stylesheet" {...attr} />
207
+ ))}
208
+ {assets.js.map((attr: any) => (
209
+ <link key={attr.href} type="modulepreload" {...attr} />
210
+ ))}
211
+ <script type="module" src={assets.entry} />
212
+ </head>
213
+ <body>
214
+ <h1 className="hero">Nitro + Vite + Preact</h1>
215
+ <p>URL: {props.url.href}</p>
216
+ <div id="app">
217
+ <App />
218
+ </div>
219
+ </body>
220
+ </html>
221
+ );
222
+ }
223
+ ```
224
+
225
+ Import assets using the `?assets=client` and `?assets=ssr` query parameters. Nitro collects CSS and JS assets from each entry point, and `merge()` combines them into a single manifest. The `assets` object provides arrays of stylesheet and script attributes, plus the client entry URL. Use `renderToReadableStream` to stream HTML as Preact renders, improving time-to-first-byte.
226
+
227
+ ## 4. Create the Client Entry
228
+
229
+ The client entry hydrates the server-rendered HTML, attaching Preact's event handlers:
230
+
231
+ ```tsx [src/entry-client.tsx]
232
+ import { hydrate } from "preact";
233
+ import { App } from "./app.tsx";
234
+
235
+ function main() {
236
+ hydrate(<App />, document.querySelector("#app")!);
237
+ }
238
+
239
+ main();
240
+ ```
241
+
242
+ The `hydrate` function attaches Preact to the existing server-rendered DOM inside `#app` without re-rendering it.
243
+
244
+ ## Learn More
245
+
246
+ - [Renderer](/docs/renderer)
247
+ - [Server Entry](/docs/server-entry)
@@ -0,0 +1,226 @@
1
+ # SSR with React
2
+
3
+ > Server-side rendering with React in Nitro using Vite.
4
+
5
+ <code-tree>
6
+
7
+ ```json [package.json]
8
+ {
9
+ "type": "module",
10
+ "scripts": {
11
+ "build": "vite build",
12
+ "preview": "vite preview",
13
+ "dev": "vite dev"
14
+ },
15
+ "devDependencies": {
16
+ "@types/react": "^19.2.14",
17
+ "@types/react-dom": "^19.2.3",
18
+ "@vitejs/plugin-react": "^6.0.1",
19
+ "nitro": "latest",
20
+ "react": "^19.2.4",
21
+ "react-dom": "^19.2.4",
22
+ "react-refresh": "^0.18.0",
23
+ "vite": "latest"
24
+ }
25
+ }
26
+ ```
27
+
28
+ ```json [tsconfig.json]
29
+ {
30
+ "extends": "nitro/tsconfig",
31
+ "compilerOptions": {
32
+ "jsx": "react-jsx",
33
+ "jsxImportSource": "react"
34
+ }
35
+ }
36
+ ```
37
+
38
+ ```js [vite.config.mjs]
39
+ import { defineConfig } from "vite";
40
+ import { nitro } from "nitro/vite";
41
+ import react from "@vitejs/plugin-react";
42
+
43
+ export default defineConfig({
44
+ plugins: [nitro(), react()],
45
+ environments: {
46
+ client: {
47
+ build: { rollupOptions: { input: "./src/entry-client.tsx" } },
48
+ },
49
+ },
50
+ });
51
+ ```
52
+
53
+ ```tsx [src/app.tsx]
54
+ import { useState } from "react";
55
+
56
+ export function App() {
57
+ const [count, setCount] = useState(0);
58
+ return (
59
+ <>
60
+ <h1 className="hero">Nitro + Vite + React</h1>
61
+ <button onClick={() => setCount((c) => c + 1)}>Count is {count}</button>
62
+ </>
63
+ );
64
+ }
65
+ ```
66
+
67
+ ```tsx [src/entry-client.tsx]
68
+ import "@vitejs/plugin-react/preamble";
69
+ import { hydrateRoot } from "react-dom/client";
70
+ import { App } from "./app.tsx";
71
+
72
+ hydrateRoot(document.querySelector("#app")!, <App />);
73
+ ```
74
+
75
+ ```tsx [src/entry-server.tsx]
76
+ import "./styles.css";
77
+ import { renderToReadableStream } from "react-dom/server.edge";
78
+ import { App } from "./app.tsx";
79
+
80
+ import clientAssets from "./entry-client?assets=client";
81
+ import serverAssets from "./entry-server?assets=ssr";
82
+
83
+ export default {
84
+ async fetch(_req: Request) {
85
+ const assets = clientAssets.merge(serverAssets);
86
+ return new Response(
87
+ await renderToReadableStream(
88
+ <html lang="en">
89
+ <head>
90
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
91
+ {assets.css.map((attr: any) => (
92
+ <link key={attr.href} rel="stylesheet" {...attr} />
93
+ ))}
94
+ {assets.js.map((attr: any) => (
95
+ <link key={attr.href} type="modulepreload" {...attr} />
96
+ ))}
97
+ <script type="module" src={assets.entry} />
98
+ </head>
99
+ <body id="app">
100
+ <App />
101
+ </body>
102
+ </html>
103
+ ),
104
+ { headers: { "Content-Type": "text/html;charset=utf-8" } }
105
+ );
106
+ },
107
+ };
108
+ ```
109
+
110
+ ```css [src/styles.css]
111
+ .hero {
112
+ color: orange;
113
+ }
114
+
115
+ button {
116
+ background-color: lightskyblue;
117
+ }
118
+ ```
119
+ </code-tree>
120
+
121
+ Set up server-side rendering (SSR) with React, Vite, and Nitro. This setup enables streaming HTML responses, automatic asset management, and client hydration.
122
+
123
+ ## Overview
124
+
125
+ 1. Add the Nitro Vite plugin to your Vite config
126
+ 2. Configure client and server entry points
127
+ 3. Create a server entry that renders your app to HTML
128
+ 4. Create a client entry that hydrates the server-rendered HTML
129
+
130
+ ## 1. Configure Vite
131
+ Add the Nitro and React plugins to your Vite config. Define the `client` environment with your client entry point:
132
+
133
+ ```js [vite.config.mjs]
134
+ import { defineConfig } from "vite";
135
+ import { nitro } from "nitro/vite";
136
+ import react from "@vitejs/plugin-react";
137
+
138
+ export default defineConfig({
139
+ plugins: [nitro(), react()],
140
+ environments: {
141
+ client: {
142
+ build: { rollupOptions: { input: "./src/entry-client.tsx" } },
143
+ },
144
+ },
145
+ });
146
+ ```
147
+
148
+ The `environments.client` configuration tells Vite which file to use as the browser entry point. Nitro automatically detects the server entry from files named `entry-server` or `server` in common directories.
149
+
150
+ ## 2. Create the App Component
151
+
152
+ Create a shared React component that runs on both server and client:
153
+
154
+ ```tsx [src/app.tsx]
155
+ import { useState } from "react";
156
+
157
+ export function App() {
158
+ const [count, setCount] = useState(0);
159
+ return (
160
+ <>
161
+ <h1 className="hero">Nitro + Vite + React</h1>
162
+ <button onClick={() => setCount((c) => c + 1)}>Count is {count}</button>
163
+ </>
164
+ );
165
+ }
166
+ ```
167
+
168
+ ## 3. Create the Server Entry
169
+
170
+ The server entry renders your React app to a streaming HTML response. It uses `react-dom/server.edge` for edge-compatible streaming:
171
+
172
+ ```tsx [src/entry-server.tsx]
173
+ import "./styles.css";
174
+ import { renderToReadableStream } from "react-dom/server.edge";
175
+ import { App } from "./app.tsx";
176
+
177
+ import clientAssets from "./entry-client?assets=client";
178
+ import serverAssets from "./entry-server?assets=ssr";
179
+
180
+ export default {
181
+ async fetch(_req: Request) {
182
+ const assets = clientAssets.merge(serverAssets);
183
+ return new Response(
184
+ await renderToReadableStream(
185
+ <html lang="en">
186
+ <head>
187
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
188
+ {assets.css.map((attr: any) => (
189
+ <link key={attr.href} rel="stylesheet" {...attr} />
190
+ ))}
191
+ {assets.js.map((attr: any) => (
192
+ <link key={attr.href} type="modulepreload" {...attr} />
193
+ ))}
194
+ <script type="module" src={assets.entry} />
195
+ </head>
196
+ <body id="app">
197
+ <App />
198
+ </body>
199
+ </html>
200
+ ),
201
+ { headers: { "Content-Type": "text/html;charset=utf-8" } }
202
+ );
203
+ },
204
+ };
205
+ ```
206
+
207
+ Import assets using the `?assets=client` and `?assets=ssr` query parameters. Nitro collects CSS and JS assets from each entry point, and `merge()` combines them into a single manifest. The `assets` object provides arrays of stylesheet and script attributes, plus the client entry URL. Use `renderToReadableStream` to stream HTML as React renders, improving time-to-first-byte.
208
+
209
+ ## 4. Create the Client Entry
210
+
211
+ The client entry hydrates the server-rendered HTML, attaching React's event handlers:
212
+
213
+ ```tsx [src/entry-client.tsx]
214
+ import "@vitejs/plugin-react/preamble";
215
+ import { hydrateRoot } from "react-dom/client";
216
+ import { App } from "./app.tsx";
217
+
218
+ hydrateRoot(document.querySelector("#app")!, <App />);
219
+ ```
220
+
221
+ The `@vitejs/plugin-react/preamble` import is required for React Fast Refresh during development. The `hydrateRoot` function attaches React to the existing server-rendered DOM without re-rendering it.
222
+
223
+ ## Learn More
224
+
225
+ - [Renderer](/docs/renderer)
226
+ - [Server Entry](/docs/server-entry)