nitro 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 +7261 -3812
  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 +576 -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,204 @@
1
+ # Lifecycle
2
+
3
+ > Understand how Nitro runs and serves incoming requests to your application.
4
+
5
+ ## Request lifecycle
6
+
7
+ A request can be intercepted and terminated (with or without a response) from any of these layers, in this order:
8
+
9
+ <steps>
10
+
11
+ ### `request` hook
12
+
13
+ The `request` hook is the first code that runs for every incoming request. It is registered via a [server plugin](/docs/plugins):
14
+
15
+ ```ts [plugins/request-hook.ts]
16
+ import { definePlugin } from "nitro";
17
+
18
+ export default definePlugin((nitroApp) => {
19
+ nitroApp.hooks.hook("request", (event) => {
20
+ console.log(`Incoming request on ${event.path}`);
21
+ });
22
+ });
23
+ ```
24
+
25
+ <note>
26
+
27
+ Errors thrown inside the `request` hook are captured by the [`error` hook](#error-handling) and do not terminate the request pipeline.
28
+ </note>
29
+
30
+ ### Static assets
31
+
32
+ When static asset serving is enabled (the default for most presets), Nitro checks if the request matches a file in the `public/` directory **before** any other middleware or route handler runs.
33
+
34
+ If a match is found, the static file is served immediately with appropriate `Content-Type`, `ETag`, `Last-Modified`, and `Cache-Control` headers. The request is terminated and no further middleware or routes are executed.
35
+
36
+ Static assets also support content negotiation for pre-compressed files (gzip, brotli, zstd) via the `Accept-Encoding` header.
37
+
38
+ ### Route rules
39
+
40
+ The matching route rules defined in the Nitro config will execute. Route rules run as middleware so most of them alter the response without terminating it (for instance, adding a header or setting a cache policy).
41
+
42
+ ```ts [nitro.config.ts]
43
+ import { defineConfig } from "nitro";
44
+
45
+ export default defineConfig({
46
+ routeRules: {
47
+ '/**': { headers: { 'x-nitro': 'first' } }
48
+ }
49
+ })
50
+ ```
51
+
52
+ <read-more></read-more>
53
+
54
+ ### Global middleware
55
+
56
+ Any global middleware defined in the `middleware/` directory will be run:
57
+
58
+ ```ts [middleware/info.ts]
59
+ import { defineHandler } from "nitro";
60
+
61
+ export default defineHandler((event) => {
62
+ event.context.info = { name: "Nitro" };
63
+ });
64
+ ```
65
+
66
+ <warning>
67
+
68
+ Returning from a middleware will close the request and should be avoided when possible.
69
+ </warning>
70
+
71
+ <read-more>
72
+
73
+ Learn more about Nitro middleware.
74
+ </read-more>
75
+
76
+ ### Routed middleware
77
+
78
+ Middleware that targets a specific route pattern (defined with a `route` in `middleware/`) runs after global middleware but before the matched route handler.
79
+
80
+ ### Routes
81
+
82
+ Nitro will look at defined routes in the `routes/` folder to match the incoming request.
83
+
84
+ ```ts [routes/api/hello.ts]
85
+ export default (event) => ({ world: true })
86
+ ```
87
+
88
+ <read-more>
89
+
90
+ Learn more about Nitro file-system routing.
91
+ </read-more>
92
+
93
+ If serverEntry is defined it will catch all requests not matching any other route acting as `/**` route handler.
94
+
95
+ ```ts [server.ts]
96
+ import { defineHandler } from "nitro";
97
+
98
+ export default defineHandler((event) => {
99
+ if (event.path === "/") {
100
+ return "Home page";
101
+ }
102
+ });
103
+ ```
104
+
105
+ <read-more>
106
+
107
+ Learn more about Nitro server entry.
108
+ </read-more>
109
+
110
+ ### Renderer
111
+
112
+ If no route is matched, Nitro will look for a renderer handler (defined or auto-detected) to handle the request.
113
+
114
+ <read-more>
115
+
116
+ Learn more about Nitro renderer.
117
+ </read-more>
118
+
119
+ ### `response` hook
120
+
121
+ After the response is created (from any of the layers above), the `response` hook runs. This hook receives the final `Response` object and the event, and can be used to inspect or modify response headers:
122
+
123
+ ```ts [plugins/response-hook.ts]
124
+ import { definePlugin } from "nitro";
125
+
126
+ export default definePlugin((nitroApp) => {
127
+ nitroApp.hooks.hook("response", (res, event) => {
128
+ console.log(`Response ${res.status} for ${event.path}`);
129
+ });
130
+ });
131
+ ```
132
+
133
+ <note>
134
+
135
+ The `response` hook runs for every response, including static assets, middleware-terminated requests, and error responses.
136
+ </note>
137
+ </steps>
138
+
139
+ ## Error handling
140
+
141
+ When an error occurs at any point in the request lifecycle, Nitro:
142
+
143
+ 1. Calls the `error` hook with the error and context (including the event and source tags).
144
+ 2. Passes the error to the **error handler** which converts it into an HTTP response.
145
+
146
+ ```ts [plugins/errors.ts]
147
+ import { definePlugin } from "nitro";
148
+
149
+ export default definePlugin((nitroApp) => {
150
+ nitroApp.hooks.hook("error", (error, context) => {
151
+ console.error("Captured error:", error);
152
+ // context.event - the H3 event (if available)
153
+ // context.tags - error source tags like "request", "response", "plugin"
154
+ });
155
+ });
156
+ ```
157
+ Errors are also tracked per-request in `event.req.context.nitro.errors` for inspection in later hooks.
158
+
159
+ You can provide a custom error handler in the Nitro config to control error response formatting:
160
+
161
+ ```ts [nitro.config.ts]
162
+ import { defineConfig } from "nitro";
163
+
164
+ export default defineConfig({
165
+ errorHandler: "~/error",
166
+ })
167
+ ```
168
+
169
+ Additionally, unhandled promise rejections and uncaught exceptions at the process level are automatically captured into the `error` hook with the tags `"unhandledRejection"` and `"uncaughtException"`.
170
+
171
+ ## Server shutdown
172
+
173
+ When the Nitro server is shutting down, the `close` hook is called. Use this to clean up resources such as database connections, timers, or external service handles:
174
+
175
+ ```ts [plugins/cleanup.ts]
176
+ import { definePlugin } from "nitro";
177
+
178
+ export default definePlugin((nitroApp) => {
179
+ nitroApp.hooks.hook("close", async () => {
180
+ // Clean up resources
181
+ });
182
+ });
183
+ ```
184
+
185
+ ## Hooks reference
186
+
187
+ All runtime hooks are registered through [server plugins](/docs/plugins) using `nitroApp.hooks.hook()`.
188
+
189
+ | Hook | Signature | When it runs |
190
+ | --- | --- | --- |
191
+ | `request` | `(event: HTTPEvent) => void \| Promise<void>` | Start of each request, before routing. |
192
+ | `response` | `(res: Response, event: HTTPEvent) => void \| Promise<void>` | After the response is created, before it is sent. |
193
+ | `error` | `(error: Error, context: { event?, tags? }) => void` | When any error is captured during the lifecycle. |
194
+ | `close` | `() => void` | When the Nitro server is shutting down. |
195
+
196
+ <note>
197
+
198
+ The `NitroRuntimeHooks` interface is augmentable. Deployment presets (such as Cloudflare) can extend it with platform-specific hooks.
199
+ </note>
200
+
201
+ <read-more>
202
+
203
+ Learn more about Nitro plugins and hook usage examples.
204
+ </read-more>
@@ -0,0 +1,291 @@
1
+ # OpenAPI
2
+
3
+ > Nitro can automatically generate an [OpenAPI](https://www.openapis.org/) specification from your route handlers and serve interactive API documentation.
4
+
5
+ Nitro scans all route handlers, extracts metadata defined with `defineRouteMeta`, and generates an [OpenAPI 3.1.0](https://spec.openapis.org/oas/v3.1.0) specification. Built-in UIs powered by [Scalar](https://scalar.com/) and [Swagger UI](https://swagger.io/tools/swagger-ui/) let you explore and test your API directly in the browser.
6
+
7
+ > [!IMPORTANT]
8
+ > OpenAPI support is currently experimental.
9
+
10
+ ## Enable OpenAPI
11
+
12
+ Enable OpenAPI in your Nitro configuration:
13
+
14
+ <code-group>
15
+
16
+ ```ts [nitro.config.ts]
17
+ import { defineConfig } from "nitro";
18
+
19
+ export default defineConfig({
20
+ experimental: {
21
+ openAPI: true,
22
+ },
23
+ });
24
+ ```
25
+ </code-group>
26
+
27
+ Once enabled, the following endpoints become available during development:
28
+
29
+ | Endpoint | Description |
30
+ | --- | --- |
31
+ | `/_openapi.json` | OpenAPI 3.1.0 JSON specification |
32
+ | `/_scalar` | Scalar API reference UI |
33
+ | `/_swagger` | Swagger UI |
34
+
35
+ ## Route Metadata
36
+
37
+ Use the `defineRouteMeta` macro in route handler files to provide OpenAPI metadata for each route. The `openAPI` property accepts a standard OpenAPI [Operation Object](https://spec.openapis.org/oas/v3.1.0#operation-object).
38
+
39
+ ```ts [routes/api/hello.ts]
40
+ import { defineRouteMeta, defineHandler } from "nitro";
41
+
42
+ defineRouteMeta({
43
+ openAPI: {
44
+ tags: ["greeting"],
45
+ description: "Returns a greeting message",
46
+ responses: {
47
+ 200: { description: "Successful greeting" },
48
+ },
49
+ },
50
+ });
51
+
52
+ export default defineHandler(() => {
53
+ return { message: "Hello, world!" };
54
+ });
55
+ ```
56
+
57
+ <note>
58
+
59
+ `defineRouteMeta` is a build-time macro. The metadata is statically extracted during the build and does not add any runtime overhead to your handlers.
60
+ </note>
61
+
62
+ ### Parameters
63
+
64
+ Route parameters (`:id`, `[id]`) are automatically converted to OpenAPI path parameters. You can define additional query or header parameters in the `parameters` array:
65
+
66
+ ```ts [routes/api/users/[id].get.ts]
67
+ import { defineRouteMeta, defineHandler } from "nitro";
68
+
69
+ defineRouteMeta({
70
+ openAPI: {
71
+ tags: ["users"],
72
+ description: "Get a user by their ID",
73
+ parameters: [
74
+ {
75
+ in: "query",
76
+ name: "include",
77
+ description: "Comma-separated list of related resources to include",
78
+ schema: { type: "string" },
79
+ },
80
+ ],
81
+ responses: {
82
+ 200: { description: "User found" },
83
+ 404: { description: "User not found" },
84
+ },
85
+ },
86
+ });
87
+
88
+ export default defineHandler((event) => {
89
+ const { id } = event.context.params;
90
+ return { id, name: "Alice" };
91
+ });
92
+ ```
93
+
94
+ In this example, the `id` path parameter is automatically inferred from the route pattern. Only the additional `include` query parameter needs to be declared.
95
+
96
+ ### Response Schemas
97
+
98
+ Define response content types and schemas using the standard OpenAPI `responses` object:
99
+
100
+ ```ts [routes/api/status.ts]
101
+ import { defineRouteMeta, defineHandler } from "nitro";
102
+
103
+ defineRouteMeta({
104
+ openAPI: {
105
+ description: "Returns the current server status",
106
+ responses: {
107
+ 200: {
108
+ description: "Server status",
109
+ content: {
110
+ "application/json": {
111
+ schema: {
112
+ type: "object",
113
+ properties: {
114
+ status: { type: "string", enum: ["healthy", "degraded"] },
115
+ uptime: { type: "number" },
116
+ },
117
+ },
118
+ },
119
+ },
120
+ },
121
+ },
122
+ },
123
+ });
124
+
125
+ export default defineHandler(() => {
126
+ return { status: "healthy", uptime: process.uptime() };
127
+ });
128
+ ```
129
+
130
+ ### Global Components
131
+
132
+ Use the `$global` property to define reusable schemas that are hoisted to the top-level `components` section of the OpenAPI specification. This lets you reference shared schemas with `$ref` across multiple routes.
133
+
134
+ ```ts [routes/api/users.get.ts]
135
+ import { defineRouteMeta, defineHandler } from "nitro";
136
+
137
+ defineRouteMeta({
138
+ openAPI: {
139
+ tags: ["users"],
140
+ description: "List all users",
141
+ responses: {
142
+ 200: {
143
+ description: "List of users",
144
+ content: {
145
+ "application/json": {
146
+ schema: {
147
+ type: "array",
148
+ items: { $ref: "#/components/schemas/User" },
149
+ },
150
+ },
151
+ },
152
+ },
153
+ },
154
+ $global: {
155
+ components: {
156
+ schemas: {
157
+ User: {
158
+ type: "object",
159
+ properties: {
160
+ id: { type: "string" },
161
+ name: { type: "string" },
162
+ email: { type: "string", format: "email" },
163
+ },
164
+ },
165
+ },
166
+ },
167
+ },
168
+ },
169
+ });
170
+
171
+ export default defineHandler(() => {
172
+ return [{ id: "1", name: "Alice", email: "alice@example.com" }];
173
+ });
174
+ ```
175
+
176
+ Once defined, the `User` schema can be referenced from any other route with `{ $ref: "#/components/schemas/User" }` without re-declaring it.
177
+
178
+ ### Automatic Tagging
179
+
180
+ Routes are automatically tagged based on their path prefix:
181
+
182
+ | Route prefix | Tag |
183
+ | --- | --- |
184
+ | `/api/` | API Routes |
185
+ | `/_` | Internal |
186
+ | Other | App Routes |
187
+
188
+ You can override this by specifying `tags` in the `openAPI` metadata.
189
+
190
+ ## Configuration
191
+
192
+ Configure OpenAPI behavior with the top-level `openAPI` option:
193
+
194
+ ```ts [nitro.config.ts]
195
+ import { defineConfig } from "nitro";
196
+
197
+ export default defineConfig({
198
+ experimental: {
199
+ openAPI: true,
200
+ },
201
+ openAPI: {
202
+ meta: {
203
+ title: "My API",
204
+ description: "My awesome API",
205
+ version: "2.0.0",
206
+ },
207
+ },
208
+ });
209
+ ```
210
+
211
+ ### `meta`
212
+
213
+ Set the API metadata that appears in the specification's `info` object:
214
+
215
+ | Property | Default | Description |
216
+ | --- | --- | --- |
217
+ | `title` | `"Nitro Server Routes"` | API title |
218
+ | `description` | — | API description |
219
+ | `version` | `"1.0.0"` | API version |
220
+
221
+ ### `route`
222
+
223
+ - Default: `"/_openapi.json"`
224
+ Override the path where the OpenAPI JSON specification is served:
225
+
226
+ ```ts [nitro.config.ts]
227
+ export default defineConfig({
228
+ openAPI: {
229
+ route: "/_docs/openapi.json",
230
+ },
231
+ });
232
+ ```
233
+
234
+ ### `ui`
235
+
236
+ Configure or disable the built-in API documentation UIs:
237
+
238
+ ```ts [nitro.config.ts]
239
+ export default defineConfig({
240
+ openAPI: {
241
+ ui: {
242
+ scalar: {
243
+ route: "/_docs/scalar",
244
+ theme: "purple",
245
+ },
246
+ swagger: {
247
+ route: "/_docs/swagger",
248
+ },
249
+ },
250
+ },
251
+ });
252
+ ```
253
+
254
+ Set either UI to `false` to disable it:
255
+
256
+ ```ts [nitro.config.ts]
257
+ export default defineConfig({
258
+ openAPI: {
259
+ ui: {
260
+ swagger: false,
261
+ },
262
+ },
263
+ });
264
+ ```
265
+
266
+ <read-more></read-more>
267
+
268
+ ## Production
269
+
270
+ By default, OpenAPI endpoints are only available during development. To enable them in production, set the `production` option:
271
+
272
+ ```ts [nitro.config.ts]
273
+ export default defineConfig({
274
+ openAPI: {
275
+ production: "runtime",
276
+ },
277
+ });
278
+ ```
279
+
280
+ | Value | Behavior |
281
+ | --- | --- |
282
+ | `false` | Disabled in production (default) |
283
+ | `"runtime"` | Specification is generated at runtime on each request |
284
+ | `"prerender"` | Specification is generated at build time and served as a static file |
285
+
286
+ Use `"prerender"` when the specification does not change between deployments for the best performance. Use `"runtime"` if you need dynamic server information or middleware access.
287
+
288
+ <warning>
289
+
290
+ If you enable OpenAPI in production, make sure to protect the endpoints with appropriate authentication or access control.
291
+ </warning>
@@ -0,0 +1,164 @@
1
+ # Plugins
2
+
3
+ > Use plugins to extend Nitro's runtime behavior.
4
+
5
+ Nitro plugins are **executed once** during server startup in order to allow extending Nitro's runtime behavior.
6
+ They receive `nitroApp` context, which can be used to hook into lifecycle events.
7
+
8
+ Plugins are auto-registered from the `plugins/` directory and run synchronously by file name order on the first Nitro initialization. Plugin functions themselves must be synchronous (return `void`), but the hooks they register can be async.
9
+
10
+ **Example:**
11
+
12
+ ```ts [plugins/test.ts]
13
+ import { definePlugin } from "nitro";
14
+
15
+ export default definePlugin((nitroApp) => {
16
+ console.log('Nitro plugin', nitroApp)
17
+ })
18
+ ```
19
+
20
+ If you have plugins in another directory, you can use the `plugins` option:
21
+
22
+ ```ts [nitro.config.ts]
23
+ import { defineConfig } from "nitro";
24
+
25
+ export default defineConfig({
26
+ plugins: ['my-plugins/hello.ts']
27
+ })
28
+ ```
29
+
30
+ ## The `nitroApp` context
31
+
32
+ The plugin function receives a `nitroApp` object with the following properties:
33
+
34
+ | Property | Type | Description |
35
+ | --- | --- | --- |
36
+ | `hooks` | [`HookableCore`](https://github.com/unjs/hookable) | Hook system for registering lifecycle callbacks. |
37
+ | `h3` | `H3Core` | The underlying [H3](https://github.com/h3js/h3) application instance. |
38
+ | `fetch` | `(req: Request) => Response \| Promise<Response>` | The app's internal fetch handler. |
39
+ | `captureError` | `(error: Error, context) => void` | Programmatically capture errors into the error hook pipeline. |
40
+
41
+ ## Nitro runtime hooks
42
+
43
+ You can use Nitro [hooks](https://github.com/unjs/hookable) to extend the default runtime behaviour of Nitro by registering custom functions to the lifecycle events within plugins.
44
+
45
+ **Example:**
46
+
47
+ ```ts
48
+ import { definePlugin } from "nitro";
49
+
50
+ export default definePlugin((nitroApp) => {
51
+ nitroApp.hooks.hook("close", async () => {
52
+ // Will run when nitro is being closed
53
+ });
54
+ })
55
+ ```
56
+
57
+ ### Available hooks
58
+
59
+ | Hook | Signature | Description |
60
+ | --- | --- | --- |
61
+ | `request` | `(event: HTTPEvent) => void \| Promise<void>` | Called at the start of each request. |
62
+ | `response` | `(res: Response, event: HTTPEvent) => void \| Promise<void>` | Called after the response is created. |
63
+ | `error` | `(error: Error, context: { event?: HTTPEvent, tags?: string[] }) => void` | Called when an error is captured. |
64
+ | `close` | `() => void` | Called when the Nitro server is shutting down. |
65
+
66
+ > [!NOTE]
67
+ > The `NitroRuntimeHooks` interface is augmentable. Deployment presets (such as Cloudflare) can extend it with platform-specific hooks like `cloudflare:scheduled` and `cloudflare:email`.
68
+
69
+ ### Unregistering hooks
70
+
71
+ The `hook()` method returns an unregister function that can be called to remove the hook:
72
+
73
+ ```ts
74
+ import { definePlugin } from "nitro";
75
+
76
+ export default definePlugin((nitroApp) => {
77
+ const unregister = nitroApp.hooks.hook("request", (event) => {
78
+ // ...
79
+ });
80
+
81
+ // Later, remove the hook
82
+ unregister();
83
+ });
84
+ ```
85
+
86
+ ## Examples
87
+
88
+ ### Capturing errors
89
+
90
+ You can use plugins to capture all application errors.
91
+
92
+ ```ts
93
+ import { definePlugin } from "nitro";
94
+
95
+ export default definePlugin((nitroApp) => {
96
+ nitroApp.hooks.hook("error", async (error, { event }) => {
97
+ console.error(`${event?.path} Application error:`, error)
98
+ });
99
+ })
100
+ ```
101
+
102
+ The `context` object includes an optional `tags` array that identifies the error source (e.g., `"request"`, `"response"`, `"cache"`, `"plugin"`, `"unhandledRejection"`, `"uncaughtException"`).
103
+
104
+ ### Programmatic error capture
105
+
106
+ You can use `captureError` to manually feed errors into the error hook pipeline:
107
+
108
+ ```ts
109
+ import { definePlugin } from "nitro";
110
+
111
+ export default definePlugin((nitroApp) => {
112
+ nitroApp.captureError(new Error("something went wrong"), {
113
+ tags: ["startup"],
114
+ });
115
+ });
116
+ ```
117
+
118
+ ### Graceful shutdown
119
+
120
+ Server will gracefully shutdown and wait for any background pending tasks initiated by `event.waitUntil`.
121
+
122
+ ```ts
123
+ import { definePlugin } from "nitro";
124
+
125
+ export default definePlugin((nitroApp) => {
126
+ nitroApp.hooks.hook("close", async () => {
127
+ // Clean up resources, close connections, etc.
128
+ });
129
+ });
130
+ ```
131
+
132
+ ### Request and response lifecycle
133
+
134
+ You can use plugins to register hooks that run on the request lifecycle:
135
+
136
+ ```ts
137
+ import { definePlugin } from "nitro";
138
+
139
+ export default definePlugin((nitroApp) => {
140
+ nitroApp.hooks.hook("request", (event) => {
141
+ console.log("on request", event.path);
142
+ });
143
+
144
+ nitroApp.hooks.hook("response", (res, event) => {
145
+ // Modify or inspect the response
146
+ console.log("on response", res.status);
147
+ });
148
+ });
149
+ ```
150
+
151
+ ### Modifying response headers
152
+
153
+ ```ts
154
+ import { definePlugin } from "nitro";
155
+
156
+ export default definePlugin((nitroApp) => {
157
+ nitroApp.hooks.hook("response", (res, event) => {
158
+ const { pathname } = new URL(event.req.url);
159
+ if (pathname.endsWith(".css") || pathname.endsWith(".js")) {
160
+ res.headers.append("Vary", "Origin");
161
+ }
162
+ });
163
+ });
164
+ ```