### Server Action Setup for GET Requests
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/action-queries.md
Provides an example of how to define a server action for GET requests using Nuxt Actions, including input validation with Zod.
```typescript
// server/actions/list-todos.get.ts
import { z } from 'zod'
export default defineAction({
input: z.object({
q: z.string().optional(),
}),
handler: async ({ input }) => {
return await db.todo.findMany({
where: input.q ? { title: { contains: input.q } } : undefined,
})
},
})
```
--------------------------------
### Clone and Install Dependencies
Source: https://github.com/billymaulana/nuxt-actions/blob/main/CONTRIBUTING.md
Clone the repository, navigate into the directory, and install project dependencies using pnpm.
```bash
git clone https://github.com/billymaulana/nuxt-actions.git
cd nuxt-actions
pnpm install
```
--------------------------------
### Progress Bar Example with useStreamAction
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/streaming.md
Demonstrates how to use the `useStreamAction` composable to display a real-time progress bar and file name during a streaming process. Requires setup with `processFiles` action and provides callbacks for completion.
```vue
{{ progress }}% -- {{ data?.fileName }}
```
--------------------------------
### All useAction Callbacks Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-action.md
An example showcasing all available callbacks: `onExecute`, `onSuccess`, `onError`, and `onSettled`, with console logging and UI updates.
```ts
const { execute } = useAction('/api/todos', {
method: 'POST',
onExecute(input) {
console.log('Sending:', input)
loadingOverlay.show()
},
onSuccess(data) {
console.log('Created:', data)
todos.value.push(data)
},
onError(error) {
console.error('Failed:', error.code, error.message)
if (error.fieldErrors) {
formErrors.value = error.fieldErrors
}
},
onSettled(result) {
loadingOverlay.hide()
console.log('Settled:', result.success ? 'success' : 'error')
},
})
```
--------------------------------
### Install validation libraries
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/getting-started.md
Install a compatible validation library such as Zod, Valibot, or ArkType.
```bash
pnpm add zod
```
```bash
pnpm add valibot
```
```bash
pnpm add arktype
```
--------------------------------
### Cursor-Based Pagination Setup
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/infinite-queries.md
Demonstrates the setup for cursor-based pagination using `useInfiniteActionQuery`. It specifies how to extract the `nextCursor` from the last page to fetch subsequent pages.
```typescript
const { pages, fetchNextPage } = useInfiniteActionQuery(
listItems,
undefined,
{
getNextPageParam: (lastPage) => lastPage.nextCursor,
},
)
```
--------------------------------
### Prepare for Development
Source: https://github.com/billymaulana/nuxt-actions/blob/main/CONTRIBUTING.md
Generate type stubs and start the development server with the playground environment.
```bash
pnpm run dev:prepare
pnpm run dev
```
--------------------------------
### Complete Contact Form Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/use-action.md
A full example demonstrating input handling, loading states, error display, and success feedback for a contact form using useAction.
```vue
```
--------------------------------
### Install Nuxt Actions Module
Source: https://github.com/billymaulana/nuxt-actions/blob/main/README.md
Install the nuxt-actions module using the nuxi command. This is the first step to integrate the module into your Nuxt project.
```bash
npx nuxi module add nuxt-actions
```
--------------------------------
### Install nuxt-actions manually
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/getting-started.md
Install nuxt-actions using your preferred package manager (pnpm, npm, or yarn).
```bash
pnpm add nuxt-actions
```
```bash
npm install nuxt-actions
```
```bash
yarn add nuxt-actions
```
--------------------------------
### Install Validation Library (ArkType)
Source: https://github.com/billymaulana/nuxt-actions/blob/main/README.md
Install ArkType, a high-performance validation library, to use with nuxt-actions. It offers the fastest runtime performance.
```bash
# ArkType (fastest runtime)
pnpm add arktype
```
--------------------------------
### GET Action with Query Parameters
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-action.md
Shows how to perform a GET request to fetch users, sending input as query parameters. The input object is automatically converted to a query string.
```vue
```
--------------------------------
### DELETE Action Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-action.md
A simple example of performing a DELETE request to remove a todo item, with success and refresh callbacks.
```vue
```
--------------------------------
### Basic Infinite Scroll Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-infinite-action-query.md
Demonstrates how to implement a basic infinite scroll with `useInfiniteActionQuery`, fetching a list of todos and providing a button to load more.
```vue
{{ todo.title }}
```
--------------------------------
### Install Validation Library (Valibot)
Source: https://github.com/billymaulana/nuxt-actions/blob/main/README.md
Install Valibot, a lightweight validation library, to use with nuxt-actions. It is known for its small bundle size.
```bash
# Valibot (smallest bundle)
pnpm add valibot
```
--------------------------------
### Timeout Configuration Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-action.md
Shows how to set a custom timeout for a server action request using the `timeout` option.
```typescript
const { execute } = useAction('/api/slow-endpoint', {
timeout: 5000, // 5 second timeout
})
```
--------------------------------
### Install Validation Library (Zod)
Source: https://github.com/billymaulana/nuxt-actions/blob/main/README.md
Install Zod, a popular validation library, to use with nuxt-actions for input validation. This is recommended for most users.
```bash
# Zod (most popular)
pnpm add zod
```
--------------------------------
### Custom Headers Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-action.md
Demonstrates how to provide a function to the `headers` option to dynamically set request headers, such as an Authorization token.
```typescript
const { execute } = useAction('/api/todos', {
headers: () => ({ Authorization: `Bearer ${token.value}` }),
})
```
--------------------------------
### Example: With String Path
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-stream-action-query.md
Illustrates using useStreamActionQuery with a string path for an API endpoint, specifying input and chunk types manually.
```APIDOC
### With String Path
```ts
const { execute, chunks, fromCache } = useStreamActionQuery<
{ prompt: string },
{ text: string }
>('/api/stream/generate', {
cacheKey: 'generate-stream',
})
await execute({ prompt: 'Hello' })
```
```
--------------------------------
### Local Development Commands
Source: https://github.com/billymaulana/nuxt-actions/blob/main/README.md
Commands for setting up and developing the nuxt-actions module locally. Includes dependency installation, type generation, development server, linting, and testing.
```bash
# Install dependencies
pnpm install
# Generate type stubs
pnpm run dev:prepare
# Develop with the playground
pnpm run dev
# Run ESLint
pnpm run lint
# Run Vitest
pnpm run test
pnpm run test:watch
# Build the module
pnpm run prepack
```
--------------------------------
### Create a Feature Branch
Source: https://github.com/billymaulana/nuxt-actions/blob/main/CONTRIBUTING.md
Branching strategy for new features, starting from the 'main' branch.
```bash
git checkout -b feat/my-feature
```
--------------------------------
### InferOutput Usage Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/types.md
Shows how to use InferInput and InferOutput with Zod, illustrating how output types can differ from input types after transformations.
```typescript
import { z } from 'zod'
const schema = z.object({ count: z.coerce.number() })
type Input = InferInput // { count: number }
type Output = InferOutput // { count: number }
```
--------------------------------
### InferInput Usage Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/types.md
Demonstrates how to use the InferInput type helper with Zod to infer the input type of a schema.
```typescript
import { z } from 'zod'
const schema = z.object({ title: z.string() })
type Input = InferInput
// { title: string }
```
--------------------------------
### Authentication Middleware Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/define-middleware.md
A basic authentication middleware that checks for a user session and throws an error if unauthorized.
```typescript
// server/utils/middleware/auth.ts
import type { User } from '~/types'
export const authMiddleware = defineMiddleware(async ({ event, next }) => {
const session = await getUserSession(event)
if (!session) {
throw createActionError({
code: 'UNAUTHORIZED',
message: 'Authentication required',
statusCode: 401,
})
}
return next({ ctx: { user: session.user as User } })
})
```
--------------------------------
### Publishable Rate Limiting Middleware (npm Package)
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/define-middleware.md
Example of creating middleware intended for distribution using `createMiddleware`. This middleware enforces rate limits.
```typescript
// Published as nuxt-actions-ratelimit
import { createMiddleware, createActionError } from 'nuxt-actions/runtime'
export const rateLimitMiddleware = createMiddleware(async ({ event, next }) => {
const ip = getRequestIP(event, { xForwardedFor: true })
await enforceRateLimit(ip)
return next()
})
```
--------------------------------
### onExecute Callback Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/use-action.md
Fires immediately when `execute` is called, before the HTTP request is made. Useful for logging or clearing previous UI state before a new request.
```typescript
const { execute } = useAction('/api/todos', {
onExecute(input) {
console.log('Sending:', input)
formErrors.value = {}
},
})
```
--------------------------------
### Debounce Configuration Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-action.md
Illustrates using the `debounce` option to delay execution of a server action, ensuring it only runs after a period of inactivity. This is useful for search inputs.
```typescript
const { execute } = useAction('/api/search', {
method: 'GET',
debounce: 300, // Wait 300ms after last call
})
// In a watcher — only the last call fires
watch(searchQuery, (q) => execute({ q }))
```
--------------------------------
### useAction with Data Transformation
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-action.md
Transform server response data before it's stored. This example sorts todos by ID in descending order after a successful GET request.
```typescript
const { execute, data } = useAction('/api/todos', {
method: 'GET',
transform: (todos) => todos.sort((a, b) => b.id - a.id),
})
```
--------------------------------
### Conditional Fetching with `enabled` Option
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/infinite-queries.md
Shows how to use the `enabled` option in `useInfiniteActionQuery` to defer fetching data until a specific condition is met. In this example, fetching starts only when `categoryId` is not null.
```typescript
const categoryId = ref(null)
const isReady = computed(() => categoryId.value !== null)
const { pages } = useInfiniteActionQuery(
listByCategory,
() => ({ categoryId: categoryId.value! }),
{
enabled: isReady,
getNextPageParam: (lastPage) => lastPage.nextCursor,
},
)
```
--------------------------------
### Rollback on Error Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/optimistic-updates.md
Demonstrates how `optimisticData` automatically reverts to a previous state when a server request fails. This snippet shows the setup for toggling a todo item with error handling and rollback.
```typescript
const { execute, optimisticData, error } = useOptimisticAction<
{ id: number },
Todo[]
>('/api/todos/toggle', {
method: 'PATCH',
currentData: todos,
updateFn: (input, current) =>
current.map(t => t.id === input.id ? { ...t, done: !t.done } : t),
onError(error) {
toast.error('Failed to update. Your changes have been reverted.')
},
})
```
--------------------------------
### Example Usage of ActionMiddleware
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/types.md
Demonstrates how to define an authentication middleware that adds user information to the context. It expects no specific input context but adds a 'user' property to the output context.
```typescript
const authMiddleware: ActionMiddleware<
Record,
{ user: User }
> = async ({ event, next }) => {
const user = await getUser(event)
return next({ ctx: { user } })
}
```
--------------------------------
### Optimistic Update Lifecycle
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/optimistic-updates.md
Visualizes the step-by-step process of `useOptimisticAction` when `execute(input)` is called, including snapshotting, optimistic updates, HTTP requests, and success/error handling.
```text
execute(input)
|
+-- Save snapshot of optimisticData
+-- optimisticData = updateFn(input, currentData) [instant]
+-- fetch(path, input)
|
+-- success: optimisticData = serverResponse
+-- error: optimisticData = snapshot [rollback]
```
--------------------------------
### Conventional Commits Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/CONTRIBUTING.md
Examples of commit messages following the Conventional Commits specification, including type, scope, and description.
```git
feat(composables): add timeout option to useAction
fix(server): handle empty body in defineAction
docs: update middleware guide
test(unit): add edge case tests for streaming
```
--------------------------------
### Creating Reusable Action Clients
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/builder-pattern.md
Illustrates how to create and configure different action clients in a shared utility file. These clients can then be imported and used across server routes.
```typescript
// server/utils/action-clients.ts
export const publicClient = createActionClient()
export const authClient = createActionClient()
.use(authMiddleware)
export const adminClient = createActionClient()
.use(authMiddleware)
.use(adminMiddleware)
```
--------------------------------
### Registration Form Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-form-action.md
Demonstrates a typical registration form using `useFormAction`. It initializes form fields, handles submission, displays field errors, and manages the dirty and submitting states for UI feedback. Includes reset functionality.
```vue
```
--------------------------------
### useOptimisticAction with All Callbacks
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-optimistic-action.md
This example showcases the comprehensive callback options available with `useOptimisticAction`, including `onExecute`, `onSuccess`, `onError`, and `onSettled`, for detailed control over action lifecycle events.
```ts
const { execute, optimisticData, data, error, status, reset } = useOptimisticAction<
{ id: number; rating: number },
Product[]
>('/api/products/rate', {
method: 'PATCH',
currentData: products,
updateFn: (input, current) =>
current.map(p => p.id === input.id ? { ...p, rating: input.rating } : p),
onExecute(input) {
console.log('Rating product:', input.id, 'with', input.rating)
},
onSuccess(serverProducts) {
products.value = serverProducts
toast.success('Rating saved')
},
onError(error) {
toast.error(`Rating failed: ${error.message}`)
},
onSettled(result) {
analytics.track('product_rated', { success: result.success })
},
})
```
--------------------------------
### useStreamAction with Options (Auth, Timeout, Callbacks)
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-stream-action.md
This example shows how to configure `useStreamAction` with custom headers for authentication, a timeout, and callback functions for handling chunks, completion, and errors.
```APIDOC
## `useStreamAction` with Options
### Description
Demonstrates advanced configuration of `useStreamAction` including authentication headers, request timeouts, and event callbacks for chunk processing, completion, and error handling.
### Example Usage
```ts
import { generateReport } from '#actions'
const { execute, chunks, status, error } = useStreamAction(generateReport, {
headers: () => ({
Authorization: `Bearer ${useAuth().token.value}`,
}),
timeout: 60000, // 60s timeout for long-running generation
onChunk(chunk) {
console.log('Progress:', chunk.progress)
},
onDone(allChunks) {
toast.success('Report generated!')
},
onError(err) {
toast.error(err.message)
},
})
```
```
--------------------------------
### Custom Error Codes Examples
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/create-action-error.md
Examples of throwing custom error codes for authentication, resource errors, rate limiting, business logic, and input validation.
```typescript
throw createActionError({ code: 'UNAUTHORIZED', message: '...', statusCode: 401 })
throw createActionError({ code: 'FORBIDDEN', message: '...', statusCode: 403 })
// Resource errors
throw createActionError({ code: 'NOT_FOUND', message: '...', statusCode: 404 })
throw createActionError({ code: 'CONFLICT', message: '...', statusCode: 409 })
throw createActionError({ code: 'GONE', message: '...', statusCode: 410 })
// Rate limiting
throw createActionError({ code: 'RATE_LIMITED', message: '...', statusCode: 429 })
// Business logic
throw createActionError({ code: 'INSUFFICIENT_FUNDS', message: '...', statusCode: 422 })
throw createActionError({ code: 'QUOTA_EXCEEDED', message: '...', statusCode: 422 })
// Input (custom validation beyond schema)
throw createActionError({ code: 'VALIDATION_ERROR', message: '...', statusCode: 422, fieldErrors: { ... } })
```
--------------------------------
### Create Action Client with Middleware
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/create-action-client.md
Initialize an action client with an array of middleware. This is equivalent to calling `.use()` for each middleware individually.
```typescript
const client = createActionClient({
middleware: [authMiddleware, rateLimitMiddleware],
})
```
--------------------------------
### Basic POST Action with useAction
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-action.md
Demonstrates a basic POST request to create a todo item. Handles success and error callbacks for user feedback.
```vue
```
--------------------------------
### Client-side Call for GET Action
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/define-action.md
This snippet shows how to call a Nuxt Action from the client-side using the `useAction` composable. It specifies the method as 'GET' and passes input parameters for pagination and search.
```typescript
const { execute, data } = useAction<
{ page: number; limit: number; search?: string },
{ posts: Post[]; pagination: Pagination }
>('/api/posts', { method: 'GET' })
await execute({ page: 1, limit: 20, search: 'nuxt' })
```
--------------------------------
### Using Middleware with createActionClient
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/define-middleware.md
Demonstrates building an action client with multiple middleware (`authMiddleware`, `loggingMiddleware`, `rateLimitMiddleware`) using the `.use()` method. The subsequent action handler can access context properties from these middleware.
```typescript
// server/utils/action-clients.ts
export const authClient = createActionClient()
.use(authMiddleware)
.use(loggingMiddleware)
.use(rateLimitMiddleware)
// server/api/todos.post.ts
export default authClient
.schema(z.object({ title: z.string() }))
.action(async ({ input, ctx }) => {
return await db.todo.create({
data: { title: input.title, userId: ctx.user.id },
})
})
```
--------------------------------
### Create Schema-less Action for GET Endpoint
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/builder-pattern.md
Defines a simple action without input validation using `.action()`. This is suitable for GET requests or when input is derived from route parameters or headers.
```typescript
// server/api/health.get.ts
export default publicClient
.action(async () => {
const dbLatency = await measureDbLatency()
return {
status: 'ok',
timestamp: Date.now(),
dbLatencyMs: dbLatency,
}
})
```
--------------------------------
### useActionQuery
Source: https://github.com/billymaulana/nuxt-actions/blob/main/README.md
Client composable for SSR-capable GET action queries, wrapping `useAsyncData`.
```APIDOC
## useActionQuery(action, input?, options?)
### Description
A client-side composable designed for Server-Side Rendering (SSR) of GET requests to actions. It wraps Nuxt's `useAsyncData` composable, providing a convenient way to fetch data with options for SSR execution, lazy loading, immediate execution, and default values.
### Options
#### `server`
- **Type**: `boolean`
- **Default**: `true`
- **Description**: Determines if the action should run on the server during SSR.
#### `lazy`
- **Type**: `boolean`
- **Default**: `false`
- **Description**: If true, the navigation will not be blocked while waiting for the data.
#### `immediate`
- **Type**: `boolean`
- **Default**: `true`
- **Description**: If true, the action query will execute immediately upon component setup.
#### `default`
- **Type**: `() => T`
- **Description**: A factory function that provides a default value for the data before it's fetched.
### Returns
An object containing:
- `data`: The fetched data.
- `error`: Any error that occurred during data fetching.
- `status`: The current status of the data fetching ('idle', 'pending', 'success', 'error').
- `pending`: Boolean indicating if the data is currently being fetched.
- `refresh`: Function to re-fetch the data.
- `clear`: Function to clear the fetched data and reset the state.
```
--------------------------------
### Basic List Query with useActionQuery
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-action-query.md
Fetches a list of todos using the `listTodos` action. Displays a loading state while data is being fetched.
```vue
Loading...
{{ todo.title }}
```
--------------------------------
### Page Number Pagination Setup
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/infinite-queries.md
Shows how to configure page number pagination. It initializes with page 1 and calculates the next page number based on the current page and total pages available.
```typescript
const { pages, fetchNextPage } = useInfiniteActionQuery(
listItems,
undefined,
{
initialPageParam: 1,
getNextPageParam: (lastPage) => {
return lastPage.page < lastPage.totalPages ? lastPage.page + 1 : undefined
},
},
)
```
--------------------------------
### createActionClient()
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/create-action-client.md
Initializes an ActionClient builder. It can optionally be pre-seeded with middleware.
```APIDOC
## createActionClient()
### Description
Creates a builder-based action client for composing actions with shared middleware, schemas, and metadata. Each method returns a new immutable instance, making it safe to share and extend base clients across multiple actions.
### Type Signature
```ts
function createActionClient>(
opts?: { middleware?: ActionMiddleware[] }
): ActionClient
```
### Type Parameters
| Parameter | Default | Description |
|---|---|---|
| `TCtx` | `Record` | The accumulated context type. Starts empty and grows as `.use()` adds middleware that extends context. |
### Constructor Options
```ts
interface CreateActionClientOptions {
/** Pre-seed the client with middleware. Equivalent to calling .use() for each entry. */
middleware?: ActionMiddleware[];
}
```
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
| `middleware` | `ActionMiddleware[]` | No | `[]` | An initial array of middleware to include in the chain. |
### Example: Constructor with Middleware
```ts
// Equivalent to createActionClient().use(authMiddleware).use(rateLimitMiddleware)
const client = createActionClient({
middleware: [authMiddleware, rateLimitMiddleware],
})
```
```
--------------------------------
### Define GET Action with Zod Input Validation
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/define-action.md
This snippet demonstrates defining a server-side action for GET requests. It uses Zod for input validation and coercion, ensuring data types like numbers and booleans are correctly handled from query parameters. The handler fetches posts based on search criteria and provides pagination details.
```typescript
// server/api/posts.get.ts
import { z } from 'zod'
export default defineAction({
input: z.object({
page: z.coerce.number().int().min(1).default(1),
limit: z.coerce.number().int().min(1).max(100).default(20),
search: z.string().optional(),
published: z.enum(['true', 'false']).transform(v => v === 'true').optional(),
}),
handler: async ({ input }) => {
const offset = (input.page - 1) * input.limit
const [posts, total] = await Promise.all([
db.post.findMany({
where: input.search
? { title: { contains: input.search } }
: undefined,
skip: offset,
take: input.limit,
orderBy: { createdAt: 'desc' },
}),
db.post.count(),
])
return {
posts,
pagination: {
page: input.page,
limit: input.limit,
total,
totalPages: Math.ceil(total / input.limit),
},
}
},
})
```
--------------------------------
### Trigger Release Process
Source: https://github.com/billymaulana/nuxt-actions/blob/main/CONTRIBUTING.md
Initiate the release process, which includes linting, testing, building, and publishing.
```bash
pnpm run release
```
--------------------------------
### useStreamAction with String Path
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-stream-action.md
Example of using `useStreamAction` with a string path for manual generic type definition.
```typescript
import { useStreamAction } from '#imports'
// Assuming '/api/chat' is the server action endpoint
const { execute, stop, chunks, data, status, error } = useStreamAction<{
prompt: string;
}, string>('/api/chat', {
onChunk: (chunk) => {
console.log('Received chunk:', chunk)
},
onDone: (allChunks) => {
console.log('Stream finished. All chunks:', allChunks)
},
onError: (err) => {
console.error('Stream error:', err)
},
})
// To start the stream:
// execute({ prompt: 'Tell me a story.' })
// To stop the stream:
// stop()
```
--------------------------------
### useActionQuery with String Path
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-action-query.md
Example of using useActionQuery with a string path for manual generic type specification.
```typescript
interface UserProfile { id: number; name: string }
const { data, error, pending, refresh } = useActionQuery('/api/user/profile')
```
--------------------------------
### Offset-Based Pagination Setup
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/infinite-queries.md
Illustrates the configuration for offset-based pagination. It sets an initial page parameter and defines `getNextPageParam` to calculate the next offset based on the total number of fetched items.
```typescript
const { pages, fetchNextPage } = useInfiniteActionQuery(
listItems,
undefined,
{
initialPageParam: 0,
getNextPageParam: (lastPage, allPages) => {
const totalFetched = allPages.reduce((sum, p) => sum + p.items.length, 0)
return totalFetched < lastPage.total ? totalFetched : undefined
},
},
)
```
--------------------------------
### useStreamAction with Typed Reference
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-stream-action.md
Example of using `useStreamAction` with a typed action reference for end-to-end type inference.
```typescript
import { useStreamAction } from '#imports'
import type { TypedActionReference } from 'nuxt-typed-api'
// Assuming 'aiChat' is a typed action reference
// const aiChat = ...
const { execute, stop, chunks, data, status, error } = useStreamAction(aiChat, {
onChunk: (chunk) => {
console.log('Received chunk:', chunk)
},
onDone: (allChunks) => {
console.log('Stream finished. All chunks:', allChunks)
},
onError: (err) => {
console.error('Stream error:', err)
},
})
// To start the stream:
// execute({ prompt: 'Hello, world!' })
// To stop the stream:
// stop()
```
--------------------------------
### useActionQuery with Input and Options
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-action-query.md
Demonstrates passing input and options to useActionQuery for fetching user data.
```typescript
const userId = ref(1)
const { data, error, pending, refresh } = useActionQuery(
getUserById,
() => ({ id: userId.value })
)
```
--------------------------------
### Admin Authorization Middleware Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/define-middleware.md
Middleware to check if the user has an 'admin' role, throwing a forbidden error if not.
```typescript
// server/utils/middleware/admin.ts
export const adminMiddleware = defineMiddleware<
{ user: { role: string } },
{ isAdmin: true }
>(async ({ ctx, next }) => {
if (ctx.user.role !== 'admin') {
throw createActionError({
code: 'FORBIDDEN',
message: 'Admin access required',
statusCode: 403,
})
}
return next({ ctx: { isAdmin: true as const } })
})
```
--------------------------------
### useActionQuery with Typed Action Reference
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/use-action-query.md
Example of using useActionQuery with a typed action reference for end-to-end type inference.
```typescript
import type { TypedActionReference } from '#actions'
// Assuming 'myTypedAction' is a typed action reference
const { data, error, pending, refresh } = useActionQuery(myTypedAction)
```
--------------------------------
### Client-side Error Response Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/create-action-error.md
Illustrates the JSON structure received by the client when a createActionError is thrown and caught by defineAction.
```json
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Todo not found",
"statusCode": 404
}
}
```
--------------------------------
### ActionResult Usage Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/types.md
Demonstrates how to handle the ActionResult type, checking for success or failure and accessing the corresponding data or error.
```typescript
const result: ActionResult = await execute({ title: 'Buy milk' })
if (result.success) {
console.log(result.data) // Todo
} else {
console.error(result.error) // ActionError
}
```
--------------------------------
### Using an Authenticated Client in an Action
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/builder-pattern.md
Demonstrates how to use a pre-configured authenticated client (`authClient`) to define a new server action. It includes schema validation and type-safe context.
```typescript
// server/api/teams.post.ts
import { z } from 'zod'
export default authClient
.schema(z.object({
name: z.string().min(1, 'Team name is required').max(100),
description: z.string().max(500).optional(),
}))
.action(async ({ input, ctx }) => {
const team = await db.team.create({
data: {
name: input.name,
description: input.description,
ownerId: ctx.user.id,
},
})
return team
})
```
--------------------------------
### Directory Structure for Nuxt Actions
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/e2e-type-inference.md
Illustrates the standard directory structure for organizing Nuxt server action files within the `server/actions/` directory.
```bash
server/
actions/
create-todo.ts # POST /api/_actions/create-todo
list-todos.get.ts # GET /api/_actions/list-todos
update-todo.put.ts # PUT /api/_actions/update-todo
delete-todo.delete.ts # DELETE /api/_actions/delete-todo
```
--------------------------------
### Logging Middleware Example
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/define-middleware.md
A middleware that logs request details such as method, path, and duration, and adds a request ID to the context.
```typescript
// server/utils/middleware/logging.ts
export const loggingMiddleware = defineMiddleware(async ({ event, next }) => {
const requestId = crypto.randomUUID()
const start = Date.now()
const result = await next({ ctx: { requestId } })
console.log(JSON.stringify({
requestId,
method: event.method,
path: event.path,
duration: Date.now() - start,
}))
return result
})
```
--------------------------------
### Create Action Client with Chained Middleware
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/builder-pattern.md
Initializes an action client and chains authentication and organization middleware to it. Subsequent actions will have access to user and organization context.
```typescript
export const orgClient = createActionClient()
.use(authMiddleware) // adds ctx.user
.use(organizationMiddleware) // adds ctx.organization, ctx.memberRole
```
--------------------------------
### Configuring HTTP Methods for useAction
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/guide/use-action.md
Demonstrates how to configure different HTTP methods for `useAction`. By default, it sends POST requests. Input is sent as the request body for most methods, but as query parameters for GET.
```typescript
// POST (default) -- input sent as request body
const { execute } = useAction('/api/todos', { method: 'POST' })
// GET -- input sent as query parameters
const { execute } = useAction('/api/todos', { method: 'GET' })
// PUT -- input sent as request body
const { execute } = useAction('/api/todos/1', { method: 'PUT' })
// PATCH -- input sent as request body
const { execute } = useAction('/api/todos/1', { method: 'PATCH' })
// DELETE -- input sent as request body
const { execute } = useAction('/api/todos/1', { method: 'DELETE' })
```
--------------------------------
### Passing Context Forward with next()
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/define-middleware.md
Example of calling next() to add user information to the context for downstream middleware and handlers.
```typescript
export const authMiddleware = defineMiddleware(async ({ event, next }) => {
const session = await getUserSession(event)
return next({ ctx: { user: session.user } })
// Downstream middleware and handler receive ctx.user
})
```
--------------------------------
### Run Unit Tests
Source: https://github.com/billymaulana/nuxt-actions/blob/main/CONTRIBUTING.md
Execute unit tests, with options for watch mode, coverage reporting, and type checking.
```bash
# Run unit tests
pnpm run test
# Run with watch mode
pnpm run test:watch
# Run with coverage (100% threshold enforced)
pnpm run test:coverage
# Run type checking
pnpm run test:types
# Run compile-time type tests
pnpm run test:type-tests
```
--------------------------------
### SSE Protocol - Done Marker
Source: https://github.com/billymaulana/nuxt-actions/blob/main/docs/api/define-stream-action.md
Example of a 'done' marker sent to the client to signal the completion of a Server-Sent Events stream.
```text
data: {"__actions_done":true}
```