mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-12 03:38:07 +00:00
docs: tweaks for data fetching, server routes and composables (#6653)
This commit is contained in:
parent
63ccec6bdc
commit
3730ba88f5
@ -225,7 +225,7 @@ export const fetchWithCookie = async (url: string) => {
|
|||||||
```vue
|
```vue
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
// This composable will automatically pass cookies to the client
|
// This composable will automatically pass cookies to the client
|
||||||
const result = await fetchWithCookie("/api/with-cookie")
|
const result = await fetchWithCookie('/api/with-cookie')
|
||||||
onMounted(() => console.log(document.cookie))
|
onMounted(() => console.log(document.cookie))
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
@ -13,7 +13,7 @@ The handler can directly return JSON data, a `Promise` or use `event.res.end()`
|
|||||||
|
|
||||||
Create a new file in `server/api/hello.ts`:
|
Create a new file in `server/api/hello.ts`:
|
||||||
|
|
||||||
```ts [/server/api/hello.ts]
|
```ts [server/api/hello.ts]
|
||||||
export default defineEventHandler((event) => {
|
export default defineEventHandler((event) => {
|
||||||
return {
|
return {
|
||||||
api: 'works'
|
api: 'works'
|
||||||
@ -30,17 +30,17 @@ For adding server routes without `/api` prefix, you can instead put them into `~
|
|||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
```ts [/server/routes/hello.ts]
|
```ts [server/routes/hello.ts]
|
||||||
export default defineEventHandler(() => 'Hello World!')
|
export default defineEventHandler(() => 'Hello World!')
|
||||||
```
|
```
|
||||||
|
|
||||||
Given the Example above, the `/hello` route will be accessible at <http://localhost:3000/hello>.
|
Given the example above, the `/hello` route will be accessible at <http://localhost:3000/hello>.
|
||||||
|
|
||||||
## Server Middleware
|
## Server Middleware
|
||||||
|
|
||||||
Nuxt will automatically read in any file in the `~/server/middleware` to create server middleware for your project.
|
Nuxt will automatically read in any file in the `~/server/middleware` to create server middleware for your project.
|
||||||
|
|
||||||
Middleware handlers will run on every request before any other server route to add check and some headers, log requests, or extend the event's request object.
|
Middleware handlers will run on every request before any other server route to add or check headers, log requests, or extend the event's request object.
|
||||||
|
|
||||||
::alert{type=warning}
|
::alert{type=warning}
|
||||||
Middleware handlers should not return anything (nor close or respond to the request) and only inspect or extend the request context or throw an error.
|
Middleware handlers should not return anything (nor close or respond to the request) and only inspect or extend the request context or throw an error.
|
||||||
@ -48,13 +48,13 @@ Middleware handlers should not return anything (nor close or respond to the requ
|
|||||||
|
|
||||||
**Examples:**
|
**Examples:**
|
||||||
|
|
||||||
```ts [/server/middleware/log.ts]
|
```ts [server/middleware/log.ts]
|
||||||
export default defineEventHandler((event) => {
|
export default defineEventHandler((event) => {
|
||||||
console.log('New request: ' + event.req.url)
|
console.log('New request: ' + event.req.url)
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
```ts [/server/middleware/auth.ts]
|
```ts [server/middleware/auth.ts]
|
||||||
export default defineEventHandler((event) => {
|
export default defineEventHandler((event) => {
|
||||||
event.context.auth = { user: 123 }
|
event.context.auth = { user: 123 }
|
||||||
})
|
})
|
||||||
@ -67,18 +67,18 @@ Server routes are powered by [unjs/h3](https://github.com/unjs/h3) which comes w
|
|||||||
::ReadMore{link="https://www.jsdocs.io/package/h3#package-index-functions" title="Available H3 Request Helpers"}
|
::ReadMore{link="https://www.jsdocs.io/package/h3#package-index-functions" title="Available H3 Request Helpers"}
|
||||||
::
|
::
|
||||||
|
|
||||||
You can add more helpers by yourself inside the `~/server/utils` directory.
|
You can add more helpers yourself inside the `~/server/utils` directory.
|
||||||
|
|
||||||
## Usage Examples
|
## Usage Examples
|
||||||
|
|
||||||
### Matching Route Parameters
|
### Matching Route Parameters
|
||||||
|
|
||||||
Server routes can use dynamic parameters within brackets in the file name like `/api/hello/[name].ts` and accessed via `event.context.params`.
|
Server routes can use dynamic parameters within brackets in the file name like `/api/hello/[name].ts` and be accessed via `event.context.params`.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
```ts [/server/api/hello/[name].ts]
|
```ts [server/api/hello/[name].ts]
|
||||||
export default defineEventHandler(event => `Hello, ${event.context.params.name}!`)
|
export default defineEventHandler((event) => `Hello, ${event.context.params.name}!`)
|
||||||
```
|
```
|
||||||
|
|
||||||
You can now universally call this API using `await $fetch('/api/hello/nuxt')` and get `Hello, nuxt!`.
|
You can now universally call this API using `await $fetch('/api/hello/nuxt')` and get `Hello, nuxt!`.
|
||||||
@ -87,15 +87,15 @@ You can now universally call this API using `await $fetch('/api/hello/nuxt')` an
|
|||||||
|
|
||||||
Handle file names can be suffixed with `.get`, `.post`, `.put`, `.delete`, ... to match request's [HTTP Method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods).
|
Handle file names can be suffixed with `.get`, `.post`, `.put`, `.delete`, ... to match request's [HTTP Method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods).
|
||||||
|
|
||||||
```ts [/server/api/test.get.ts]
|
```ts [server/api/test.get.ts]
|
||||||
export default defineEventHandler(() => 'Test get handler')
|
export default defineEventHandler(() => 'Test get handler')
|
||||||
```
|
```
|
||||||
|
|
||||||
```ts [/server/api/test.post.ts]
|
```ts [server/api/test.post.ts]
|
||||||
export default defineEventHandler(() => 'Test post handler')
|
export default defineEventHandler(() => 'Test post handler')
|
||||||
```
|
```
|
||||||
|
|
||||||
Given the Example above, fetching `/test` with:
|
Given the example above, fetching `/test` with:
|
||||||
|
|
||||||
- **GET** method: Returns `Test get handler`
|
- **GET** method: Returns `Test get handler`
|
||||||
- **POST** method: Returns `Test post handler`
|
- **POST** method: Returns `Test post handler`
|
||||||
@ -107,17 +107,17 @@ Catch-all routes are helpful for fallback route handling. For example, creating
|
|||||||
|
|
||||||
**Examples:**
|
**Examples:**
|
||||||
|
|
||||||
```ts [/server/api/foo/[...].ts]
|
```ts [server/api/foo/[...].ts]
|
||||||
export default defineEventHandler(() => `Default foo handler`)
|
export default defineEventHandler(() => `Default foo handler`)
|
||||||
```
|
```
|
||||||
|
|
||||||
```ts [/server/api/[...].ts]
|
```ts [server/api/[...].ts]
|
||||||
export default defineEventHandler(() => `Default api handler`)
|
export default defineEventHandler(() => `Default api handler`)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Handling Requests with Body
|
### Handling Requests with Body
|
||||||
|
|
||||||
```ts [/server/api/submit.post.ts]
|
```ts [server/api/submit.post.ts]
|
||||||
export default defineEventHandler(async (event) => {
|
export default defineEventHandler(async (event) => {
|
||||||
const body = await useBody(event)
|
const body = await useBody(event)
|
||||||
return { body }
|
return { body }
|
||||||
@ -134,7 +134,7 @@ We are using `submit.post.ts` in the filename only to match requests with `POST`
|
|||||||
|
|
||||||
Sample query `/api/query?param1=a¶m2=b`
|
Sample query `/api/query?param1=a¶m2=b`
|
||||||
|
|
||||||
```ts [/server/api/query.get.ts]
|
```ts [server/api/query.get.ts]
|
||||||
export default defineEventHandler((event) => {
|
export default defineEventHandler((event) => {
|
||||||
const query = useQuery(event)
|
const query = useQuery(event)
|
||||||
return { a: query.param1, b: query.param2 }
|
return { a: query.param1, b: query.param2 }
|
||||||
@ -143,7 +143,7 @@ export default defineEventHandler((event) => {
|
|||||||
|
|
||||||
### Accessing Runtime Config
|
### Accessing Runtime Config
|
||||||
|
|
||||||
```ts [/server/api/foo.ts]
|
```ts [server/api/foo.ts]
|
||||||
|
|
||||||
export default defineEventHandler((event) => {
|
export default defineEventHandler((event) => {
|
||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
@ -164,10 +164,10 @@ export default defineEventHandler((event) => {
|
|||||||
|
|
||||||
### Nitro Configuration
|
### Nitro Configuration
|
||||||
|
|
||||||
You can use `nitro` key in `nuxt.config` to directly set [Nitro Configuration](https://nitro.unjs.io/config/).
|
You can use `nitro` key in `nuxt.config` to directly set [Nitro configuration](https://nitro.unjs.io/guide/config).
|
||||||
|
|
||||||
::alert{type=warning}
|
::alert{type=warning}
|
||||||
This is an advanced option. Custom config can affect production deployments and we upgrade Nitro in semver-minor versions of Nuxt 3. meaning, configuration interface might be changed over the time.
|
This is an advanced option. Custom config can affect production deployments, as the configuration interface might change over time when Nitro is upgraded in semver-minor versions of Nuxt.
|
||||||
::
|
::
|
||||||
|
|
||||||
```ts [nuxt.config.ts]
|
```ts [nuxt.config.ts]
|
||||||
@ -181,7 +181,7 @@ export default defineNuxtConfig({
|
|||||||
|
|
||||||
### Using a Nested Router
|
### Using a Nested Router
|
||||||
|
|
||||||
```ts [/server/api/hello.ts]
|
```ts [server/api/hello.ts]
|
||||||
import { createRouter } from 'h3'
|
import { createRouter } from 'h3'
|
||||||
|
|
||||||
const router = createRouter()
|
const router = createRouter()
|
||||||
@ -193,9 +193,9 @@ export default router
|
|||||||
|
|
||||||
### Sending Streams (Experimental)
|
### Sending Streams (Experimental)
|
||||||
|
|
||||||
**Note:** This is an experimental feature and available only within Node.js environments.
|
**Note:** This is an experimental feature and is only available within Node.js environments.
|
||||||
|
|
||||||
```ts [/server/api/foo.get.ts]
|
```ts [server/api/foo.get.ts]
|
||||||
import fs from 'node:fs'
|
import fs from 'node:fs'
|
||||||
import { sendStream } from 'h3'
|
import { sendStream } from 'h3'
|
||||||
|
|
||||||
@ -206,17 +206,17 @@ export default defineEventHandler((event) => {
|
|||||||
|
|
||||||
### Return a Legacy Handler or Middleware
|
### Return a Legacy Handler or Middleware
|
||||||
|
|
||||||
```ts [/server/api/legacy.ts]
|
```ts [server/api/legacy.ts]
|
||||||
export default (req, res) => {
|
export default (req, res) => {
|
||||||
res.end('Legacy handler')
|
res.end('Legacy handler')
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
::alert{type=warning}
|
::alert{type=warning}
|
||||||
Legacy support is possible using [unjs/h3](https://github.com/unjs/h3) but it advised to avoid legacy handlers as much as you can.
|
Legacy support is possible using [unjs/h3](https://github.com/unjs/h3), but it is advised to avoid legacy handlers as much as you can.
|
||||||
::
|
::
|
||||||
|
|
||||||
```ts [/server/middleware/legacy.ts]
|
```ts [server/middleware/legacy.ts]
|
||||||
export default (req, res, next) => {
|
export default (req, res, next) => {
|
||||||
console.log('Legacy middleware')
|
console.log('Legacy middleware')
|
||||||
next()
|
next()
|
||||||
@ -229,7 +229,7 @@ Never combine `next()` callback with a legacy middleware that is `async` or retu
|
|||||||
|
|
||||||
### Server Storage
|
### Server Storage
|
||||||
|
|
||||||
Nitro Provides a cross platform [Stroage Layer](https://nitro.unjs.io/guide/storage.html). In oder to configure additional storage mountpoints, you can use `nitro.storage`.
|
Nitro provides a cross-platform [storage layer](https://nitro.unjs.io/guide/storage.html). In order to configure additional storage mount points, you can use `nitro.storage`.
|
||||||
|
|
||||||
#### Example: Using Redis
|
#### Example: Using Redis
|
||||||
|
|
||||||
@ -246,8 +246,8 @@ export default defineNuxtConfig({
|
|||||||
host: "127.0.0.1", // Redis host
|
host: "127.0.0.1", // Redis host
|
||||||
username: "", // needs Redis >= 6
|
username: "", // needs Redis >= 6
|
||||||
password: "",
|
password: "",
|
||||||
db: 0, // Defaults to 0
|
db: 0 // Defaults to 0
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -255,8 +255,8 @@ export default defineNuxtConfig({
|
|||||||
|
|
||||||
Create a new file in `server/api/test.post.ts`:
|
Create a new file in `server/api/test.post.ts`:
|
||||||
|
|
||||||
```ts [/server/api/test.post.ts]
|
```ts [server/api/test.post.ts]
|
||||||
export default defineEventHandler(async event => {
|
export default defineEventHandler(async (event) => {
|
||||||
const body = await useBody(event)
|
const body = await useBody(event)
|
||||||
await useStorage().setItem('redis:test', body)
|
await useStorage().setItem('redis:test', body)
|
||||||
return 'Data is set'
|
return 'Data is set'
|
||||||
@ -265,8 +265,8 @@ export default defineEventHandler(async event => {
|
|||||||
|
|
||||||
Create a new file in `server/api/test.get.ts`:
|
Create a new file in `server/api/test.get.ts`:
|
||||||
|
|
||||||
```ts [/server/api/test.get.ts]
|
```ts [server/api/test.get.ts]
|
||||||
export default async defineEventHandler(event => {
|
export default async defineEventHandler(async (event) => {
|
||||||
const data = await useStorage().getItem('redis:test')
|
const data = await useStorage().getItem('redis:test')
|
||||||
return data
|
return data
|
||||||
})
|
})
|
||||||
|
@ -49,40 +49,39 @@ const foo = useFoo()
|
|||||||
|
|
||||||
## How Files Are Scanned
|
## How Files Are Scanned
|
||||||
|
|
||||||
Nuxt only scans files at the top level of the `composables/` directory for composables.
|
Nuxt only scans files at the top level of the `composables/` directory, e.g.:
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
composables
|
composables
|
||||||
| - useFoo.ts // scanned
|
|
||||||
| - index.ts // scanned
|
| - index.ts // scanned
|
||||||
|
| - useFoo.ts // scanned
|
||||||
| - nested
|
| - nested
|
||||||
| --- utils.ts // not scanned
|
| --- utils.ts // not scanned
|
||||||
```
|
```
|
||||||
|
|
||||||
Only `composables/useFoo.ts` would be searched for imports.
|
Only `composables/index.ts` and `composables/useFoo.ts` would be searched for imports.
|
||||||
|
|
||||||
To get auto imports for nested modules, you could either reexport them (recommended) or configure the scanner to scan nested directories:
|
To get auto imports working for nested modules, you could either re-export them (recommended) or configure the scanner to include nested directories:
|
||||||
|
|
||||||
**Example:** re-export the composables you need from the `composables/index.ts` file:
|
**Example:** Re-export the composables you need from the `composables/index.ts` file:
|
||||||
|
|
||||||
```js [composables/index.ts]
|
```ts [composables/index.ts]
|
||||||
// Enables auto import for this export
|
// Enables auto import for this export
|
||||||
export { useBaz } from './nested/useBaz.ts'
|
export { utils } from './nested/utils.ts'
|
||||||
```
|
```
|
||||||
|
|
||||||
**Example:** Scan nested directories inside composables:
|
**Example:** Scan nested directories inside the `composables/` folder:
|
||||||
|
|
||||||
```ts [nuxt.config.ts]
|
```ts [nuxt.config.ts]
|
||||||
export default defineConfig({
|
export default defineNuxtConfig({
|
||||||
// ...
|
|
||||||
autoImports: {
|
autoImports: {
|
||||||
dirs: [
|
dirs: [
|
||||||
// Scan composables from nested directories
|
// Scan top-level modules
|
||||||
'composables/**',
|
'composables',
|
||||||
// 'composables/*/index.{ts,js,mjs,mts}' // one level directories's index.js,
|
// ... or scan modules nested one level deep with a specific name and file extension
|
||||||
//'composables/**', // Scan all nested directories
|
'composables/*/index.{ts,js,mjs,mts}',
|
||||||
|
// ... or scan all modules within given directory
|
||||||
|
'composables/**'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user