### Install next-ws and ws
Source: https://github.com/k0d13/next-ws/blob/main/README.md
Install the necessary packages using npm, pnpm, or yarn.
```bash
npm install next-ws ws
```
```bash
pnpm add next-ws ws
```
```bash
yarn add next-ws ws
```
--------------------------------
### Custom Server Setup with next-ws
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md
This example illustrates how to manually initialize next-ws when using a custom Node.js server. It involves calling `setupWebSocketServer` after the Next.js app is prepared.
```typescript
import { Server } from 'node:http';
import { parse } from 'node:url';
import next from 'next';
import { setupWebSocketServer } from 'next-ws/server';
const httpServer = new Server();
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev, customServer: true });
const handle = app.getRequestHandler();
app.prepare().then(() => {
// Setup WebSocket support
setupWebSocketServer(app);
httpServer
.on('request', async (req, res) => {
if (!req.url) return;
const parsedUrl = parse(req.url, true);
await handle(req, res, parsedUrl);
})
.listen(3000, () => {
console.log('Server ready on http://localhost:3000');
});
});
```
--------------------------------
### Usage Recommendations - Starting Point
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt
Recommends the starting point for users to navigate and understand the project documentation.
```APIDOC
## Usage Recommendations: START HERE
### Description
Guides users on where to begin their exploration of the project documentation.
### Primary Entry Point
- **README.md**: Provides navigation to all topics, explains project structure, and lists common tasks.
```
--------------------------------
### Minimal WebSocket Route Example
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md
This example demonstrates the basic structure for a WebSocket route in the Next.js App Directory. It includes the required GET handler for upgrading and the UPGRADE handler for WebSocket communication.
```typescript
// app/api/ws/route.ts
export function GET() {
return new Response('Upgrade Required', {
status: 426,
headers: {
'Connection': 'Upgrade',
'Upgrade': 'websocket',
},
});
}
export function UPGRADE(client, server, request, context) {
client.on('message', (message) => {
client.send(message);
});
}
```
--------------------------------
### Server Setup
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/INDEX.md
Sets up the WebSocket server integrated with the Next.js server.
```APIDOC
## setupWebSocketServer
### Description
Sets up the WebSocket server integrated with the Next.js server.
### Function Signature
`setupWebSocketServer(nextServer, options?)`
### Parameters
- `nextServer`: The Next.js server instance.
- `options` (object, optional): Configuration options for the WebSocket server.
```
--------------------------------
### Configuring setupWebSocketServer with an Adapter
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-setup.md
Example of passing a custom adapter to setupWebSocketServer for multi-instance deployments. Ensure the adapter is correctly implemented.
```typescript
setupWebSocketServer(nextServer, {
adapter: new RedisAdapter(),
});
```
--------------------------------
### Setup WebSocket Server (No Adapter)
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md
Use this configuration for single-instance deployments where no external message broker is needed.
```typescript
import { setupWebSocketServer } from 'next-ws/server';
setupWebSocketServer(nextServer, {
// adapter is optional; omit for single-instance deployments
});
```
--------------------------------
### Core Setup Flow
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/architecture.md
Illustrates the sequence of operations for setting up the WebSocket server, from server initialization to request handling and message broadcasting.
```mermaid
setupWebSocketServer()
↓
1. Get/Create HTTP Server (persistent.ts)
2. Get/Create WebSocket Server (persistent.ts)
3. Get/Create Request Storage (persistent.ts)
4. Attach 'upgrade' handler to HTTP server
5. For each upgrade event:
a. Convert IncomingMessage to NextRequest (request.ts)
b. Find matching route (match.ts)
c. Import route module (module.ts)
d. Extract UPGRADE or SOCKET handler
e. Run handler with RequestStorage context
f. If adapter configured, broadcast messages (adapter.ts)
```
--------------------------------
### CLI Command - Patch Installation
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
Commands to patch the installation for next-ws.
```APIDOC
### Patch Installation
```bash
npx next-ws patch # Interactive
npx next-ws patch --yes # Auto-confirm
```
```
--------------------------------
### View next-ws Version
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md
Displays the installed version of the next-ws CLI.
```bash
npx next-ws --version
```
--------------------------------
### Code Examples Overview
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt
Summarizes the quantity, types, and nature of code examples provided within the documentation.
```APIDOC
## Code Examples Overview
### Description
Details the scope and quality of code examples available in the documentation.
### Details
- Total examples: 15+
- Types of examples: Setup, usage, patterns, advanced
- All examples are real usage (no pseudocode)
```
--------------------------------
### Minimal Echo Server Setup
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
Demonstrates how to set up a basic WebSocket server that echoes messages back to the client. This involves creating a route handler and a client-side connection.
```APIDOC
## Minimal Echo Server
Create `app/api/ws/route.ts`:
```typescript
export function GET() {
const headers = new Headers();
headers.set('Connection', 'Upgrade');
headers.set('Upgrade', 'websocket');
return new Response('Upgrade Required', { status: 426, headers });
}
export function UPGRADE(client, server) {
client.on('message', (msg) => client.send(msg));
}
```
Connect from client:
```typescript
'use client';
import { useEffect } from 'react';
export default function Home() {
useEffect(() => {
const ws = new WebSocket('ws://localhost:3000/api/ws');
ws.onmessage = (e) => console.log(e.data);
ws.onopen = () => ws.send('hello');
}, []);
return
Check console
;
}
```
```
--------------------------------
### Route Structure - Basic
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
Example of a basic WebSocket route handler in Next.js.
```APIDOC
### Basic Route
```typescript
// app/api/ws/route.ts
export function GET() { /* ... */ }
export function UPGRADE(client, server, request, context) { /* ... */ }
```
```
--------------------------------
### Adapter Message Flow Example
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/architecture.md
Illustrates the message flow in a multi-instance deployment using Redis for broadcasting messages between instances via route-specific channels.
```plaintext
Instance 1 Redis Instance 2
Client 1 sends "hello" → publish(room, msg) → Subscriber listens
for room messages
Adapter.broadcast() → [redis channel] → Adapter.onMessage()
routes as rooms handler fires
```
--------------------------------
### CI/CD Environment Patch Verification
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md
Ensures a properly patched Next.js installation in CI/CD environments before building and starting the application. It automatically patches if necessary.
```bash
#!/bin/bash
npx next-ws verify --ensure
npm run build
npm start
```
--------------------------------
### Adapter Interface Example
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/README.md
Optional interface for multi-instance deployments. Enables broadcasting messages from one server instance to all instances handling the same route.
```typescript
interface Adapter {
broadcast(room: string, message: unknown): Promise;
onMessage(room: string, handler: (msg: unknown) => void): void | Promise;
close(): Promise;
}
```
--------------------------------
### Adapter Storage
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/INDEX.md
Utilities for getting and setting the adapter.
```APIDOC
## Adapter Storage
### Description
Provides functions to manage the adapter used for server communication.
### Functions
- `getAdapter()`: Retrieves the current adapter.
- `setAdapter(value)`: Sets the adapter.
```
--------------------------------
### Basic WebSocket Server Setup in Next.js
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-setup.md
Integrates next-ws with a Next.js custom server. Ensure the HTTP server is listening before calling setupWebSocketServer.
```typescript
import { Server } from 'node:http';
import { parse } from 'node:url';
import next from 'next';
import { setupWebSocketServer } from 'next-ws/server';
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev, customServer: true });
const handle = app.getRequestHandler();
const httpServer = new Server();
app.prepare().then(() => {
httpServer
.on('request', async (req, res) => {
if (!req.url) return;
const parsedUrl = parse(req.url, true);
await handle(req, res, parsedUrl);
})
.listen(3000, () => {
// Setup WebSocket support after app is ready
setupWebSocketServer(app);
console.log('Server ready on http://localhost:3000');
});
});
```
--------------------------------
### Example Usage in Custom Server with Optional Redis Adapter
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md
Demonstrates setting up a custom Next.js server with next-ws, conditionally enabling the Redis adapter if REDIS_URL is provided. This is for multi-instance deployments.
```typescript
import { Server } from 'node:http';
import Redis from 'ioredis';
import next from 'next';
import { setupWebSocketServer, type Adapter } from 'next-ws/server';
const dev = process.env.NODE_ENV !== 'production';
const hostname = process.env.HOSTNAME || 'localhost';
const port = Number.parseInt(process.env.PORT ?? '3000', 10);
// For multi-instance deployments, set REDIS_URL environment variable
const redisUrl = process.env.REDIS_URL;
class RedisAdapter implements Adapter {
private pub = new Redis(redisUrl);
private sub = new Redis(redisUrl);
// ... rest of implementation
}
const httpServer = new Server();
const app = next({ dev, hostname, port, customServer: true });
app.prepare().then(() => {
// Only use adapter if Redis is configured
if (redisUrl) {
setupWebSocketServer(app, { adapter: new RedisAdapter() });
} else {
setupWebSocketServer(app);
}
httpServer.listen(port, () => {
console.log(`Server ready on http://${hostname}:${port}`);
});
});
```
--------------------------------
### Example: Echo Server
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/handlers.md
Implement an echo server by sending back any message received from the client. This handler is called once per client connection.
```typescript
// app/api/ws/route.ts
export function GET() {
const headers = new Headers();
headers.set('Connection', 'Upgrade');
headers.set('Upgrade', 'websocket');
return new Response('Upgrade Required', { status: 426, headers });
}
export function UPGRADE(client, server, request, context) {
console.log('Client connected');
client.on('message', (message) => {
// Echo the message back to the client
client.send(message);
});
client.once('close', () => {
console.log('Client disconnected');
});
}
```
--------------------------------
### Configure npm prepare script for Patching
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md
Automatically patches Next.js on every npm install by adding the patch command to the 'prepare' script in your package.json. This ensures your installation is always up-to-date.
```json
{
"scripts": {
"prepare": "next-ws patch"
}
}
```
--------------------------------
### Setup WebSocket Server in Custom Server
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
Integrate next-ws into a custom Next.js server using `setupWebSocketServer`. This can be done directly after `app.prepare()` or with an adapter like Redis.
```typescript
import { setupWebSocketServer } from 'next-ws/server';
// In custom server after app.prepare()
setupWebSocketServer(app);
// With adapter
setupWebSocketServer(app, { adapter: new RedisAdapter() });
```
--------------------------------
### RouteContext with Catch-All Parameter
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md
Example demonstrating how to access a catch-all route parameter (e.g., 'filepath') as an array of strings from RouteContext.params.
```typescript
// Route: app/api/files/[...filepath]/route.ts
export function UPGRADE(client, server, request, context) {
const filepath = context.params.filepath; // string[]
console.log(`File path: ${filepath.join('/')}`);
}
```
--------------------------------
### Setup WebSocket Server with Redis Adapter
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md
Configure for multi-instance deployments using a custom RedisAdapter to enable broadcasting messages across server instances. Ensure REDIS_URL is set.
```typescript
import Redis from 'ioredis';
import { setupWebSocketServer, type Adapter } from 'next-ws/server';
class RedisAdapter implements Adapter {
private pub = new Redis(process.env.REDIS_URL);
private sub = new Redis(process.env.REDIS_URL);
private handlers = new Map void>>();
constructor() {
this.sub.on('message', (channel: string, msg: string) => {
const handlers = this.handlers.get(channel);
if (!handlers) return;
for (const handler of handlers) {
handler(JSON.parse(msg));
}
});
}
async broadcast(room: string, message: unknown): Promise {
const messageStr = typeof message === 'string'
? message
: JSON.stringify(message);
await this.pub.publish(room, messageStr);
}
async onMessage(
room: string,
handler: (message: unknown) => void,
): Promise {
if (!this.handlers.has(room)) {
this.handlers.set(room, new Set());
await this.sub.subscribe(room);
}
this.handlers.get(room)?.add(handler);
}
async close(): Promise {
await Promise.all([this.pub.quit(), this.sub.quit()]);
}
}
// Setup with adapter
const adapter = new RedisAdapter();
setupWebSocketServer(nextServer, { adapter });
```
--------------------------------
### Add Prepare Script to package.json
Source: https://github.com/k0d13/next-ws/blob/main/README.md
Include the prepare script in your package.json to automatically patch Next.js with next-ws during installation.
```json
{
"scripts": {
"prepare": "next-ws patch"
}
}
```
--------------------------------
### Patch Next.js Installation
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md
Applies the necessary modifications to your Next.js installation to support WebSockets. This command detects your Next.js version and applies the appropriate patch.
```bash
npx next-ws patch
```
--------------------------------
### HTTP Server Storage
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/INDEX.md
Utilities for getting, setting, and using the HTTP server instance.
```APIDOC
## HTTP Server Storage
### Description
Provides functions to manage the HTTP server instance within the application.
### Functions
- `getHttpServer()`: Retrieves the current HTTP server instance.
- `setHttpServer(value)`: Sets the HTTP server instance.
- `useHttpServer(getter)`: Uses a getter function to access the HTTP server instance.
```
--------------------------------
### Route Structure - Dynamic
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
Example of a dynamic WebSocket route handler in Next.js, using route parameters.
```APIDOC
### Dynamic Route
```typescript
// app/api/room/[roomId]/ws/route.ts
export function UPGRADE(client, server, request, context) {
const roomId = context.params.roomId as string;
}
```
```
--------------------------------
### Route Structure - Catch-All
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
Example of a catch-all WebSocket route handler in Next.js, capturing multiple path segments.
```APIDOC
### Catch-All Route
```typescript
// app/api/[...path]/ws/route.ts
export function UPGRADE(client, server, request, context) {
const path = context.params.path as string[];
}
```
```
--------------------------------
### Broadcast to All Clients Pattern
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
Example of broadcasting a received message to all connected clients.
```APIDOC
### Broadcast to All Clients
```typescript
export function UPGRADE(client, server) {
client.on('message', (data) => {
for (const other of server.clients) {
if (other.readyState === other.OPEN) {
other.send(data);
}
}
});
}
```
```
--------------------------------
### Example: Chat Broadcast
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/handlers.md
Create a chat application where messages are broadcast to all connected clients. Handles user joining and leaving notifications.
```typescript
// app/api/chat/route.ts
export function UPGRADE(client, server) {
// Notify all other clients that a new user joined
for (const other of server.clients) {
if (client !== other && other.readyState === other.OPEN) {
other.send(JSON.stringify({
type: 'user-joined',
userCount: server.clients.size,
}));
}
}
client.on('message', (message) => {
// Broadcast message to all other clients
for (const other of server.clients) {
if (client !== other && other.readyState === other.OPEN) {
other.send(message);
}
}
});
client.once('close', () => {
// Notify other clients that a user left
for (const other of server.clients) {
if (other.readyState === other.OPEN) {
other.send(JSON.stringify({
type: 'user-left',
userCount: server.clients.size - 1,
}));
}
}
});
}
```
--------------------------------
### Set Up Custom Server with Next-WS
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
This snippet shows how to integrate next-ws with a custom Node.js server for Next.js applications. Ensure you have a custom server setup.
```typescript
import { Server } from 'node:http';
import next from 'next';
import { setupWebSocketServer } from 'next-ws/server';
const app = next({ customServer: true });
const server = new Server();
app.prepare().then(() => {
setupWebSocketServer(app);
server.listen(3000);
});
```
--------------------------------
### useHttpServer()
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md
Gets or creates the HTTP server instance. If an instance already exists, it's returned. Otherwise, a getter function is called to create and store a new instance.
```APIDOC
## useHttpServer()
### Description
Gets or creates the HTTP server instance. If an instance already exists, returns it. Otherwise, calls the getter function to create one and stores it.
### Signature
```typescript
function useHttpServer(getter: () => import('node:http').Server): import('node:http').Server
```
### Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| getter | `() => import('node:http').Server` | yes | Function that creates and returns a new HTTP server instance |
### Return Value
`import('node:http').Server` — The existing HTTP server instance, or the result of calling `getter()` if none exists.
### Example
```typescript
import { Server } from 'node:http';
import { useHttpServer } from 'next-ws/server';
const server = useHttpServer(() => new Server());
```
```
--------------------------------
### WebSocket Server Storage
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/INDEX.md
Utilities for getting, setting, and using the WebSocket server instance.
```APIDOC
## WebSocket Server Storage
### Description
Provides functions to manage the WebSocket server instance within the application.
### Functions
- `getWebSocketServer()`: Retrieves the current WebSocket server instance.
- `setWebSocketServer(value)`: Sets the WebSocket server instance.
- `useWebSocketServer(getter)`: Uses a getter function to access the WebSocket server instance.
```
--------------------------------
### Production Deployment Checklist with next-ws
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md
Essential commands to run before deploying your Next.js application to production, ensuring patches are verified, the application is built, tests pass, and the server starts correctly.
```bash
# Verify patches are in place
npx next-ws verify
# Build the application
npm run build
# Test WebSocket routes
npm test
# Start the server
npm start
```
--------------------------------
### WebSocket Server Setup with Redis Adapter
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-setup.md
Configures next-ws with a custom Redis adapter for multi-instance support. This allows broadcasting messages across different server instances.
```typescript
import { Server } from 'node:http';
import Redis from 'ioredis';
import { setupWebSocketServer, type Adapter } from 'next-ws/server';
class RedisAdapter implements Adapter {
private pub = new Redis(process.env.REDIS_URL);
private sub = new Redis(process.env.REDIS_URL);
private handlers = new Map void>>();
async broadcast(room: string, message: unknown): Promise {
await this.pub.publish(room, JSON.stringify(message));
}
async onMessage(
room: string,
handler: (message: unknown) => void,
): Promise {
if (!this.handlers.has(room)) {
this.handlers.set(room, new Set());
await this.sub.subscribe(room);
}
this.handlers.get(room)?.add(handler);
}
async close(): Promise {
await Promise.all([this.pub.quit(), this.sub.quit()]);
}
}
const httpServer = new Server();
const adapter = new RedisAdapter();
app.prepare().then(() => {
// Setup with multi-instance support
setupWebSocketServer(app, { adapter });
httpServer.listen(3000);
});
```
--------------------------------
### Patch Installation Commands
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
Commands to patch the Next.js server for next-ws integration. Use the interactive mode or the `--yes` flag for automatic confirmation.
```bash
npx next-ws patch # Interactive
npx next-ws patch --yes # Auto-confirm
```
--------------------------------
### RouteContext with Simple Parameter
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md
Example demonstrating how to access a single string route parameter (e.g., 'userId') from the RouteContext.params object.
```typescript
// Route: app/api/user/[userId]/route.ts
export function UPGRADE(client, server, request, context) {
const userId = context.params.userId; // string
console.log(`User ID: ${userId}`);
}
```
--------------------------------
### Example: Dynamic Routes with Parameters
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/handlers.md
Handle WebSocket connections in dynamic routes, accessing route parameters like 'roomId'. Messages are logged and a success response is sent back.
```typescript
// app/api/room/[roomId]/route.ts
export function UPGRADE(client, server, request, context) {
const roomId = context.params.roomId as string;
console.log(`Client joined room: ${roomId}`);
// Handle messages for this room
client.on('message', (message) => {
const data = JSON.parse(message.toString());
console.log(`Message in room ${roomId}: ${data.text}`);
client.send(JSON.stringify({
success: true,
room: roomId,
}));
});
}
```
--------------------------------
### useAdapter()
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md
Gets or creates the adapter instance. If an instance already exists, it is returned. Otherwise, a getter function is called to create a new instance, which is then stored and returned.
```APIDOC
## useAdapter()
### Description
Gets or creates the adapter instance. If an instance already exists, returns it. Otherwise, calls the getter function to create one and stores it.
### Signature
```typescript
function useAdapter(getter: () => import('./helpers/adapter').Adapter): import('./helpers/adapter').Adapter
```
### Parameters
#### Path Parameters
- **getter** (() => Adapter) - Required - Function that creates and returns a new adapter instance
### Return Value
`Adapter` — The existing adapter instance, or the result of calling `getter()` if none exists.
### Example
```typescript
import { useAdapter, type Adapter } from 'next-ws/server';
const adapter = useAdapter(() => new MyCustomAdapter());
```
```
--------------------------------
### Implement Redis Adapter for Message Broadcasting
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
An example of a Redis adapter for broadcasting messages across multiple instances of your Next.js application. This requires the 'ioredis' package.
```typescript
import Redis from 'ioredis';
class RedisAdapter {
private pub = new Redis();
private sub = new Redis();
private handlers = new Map();
constructor() {
this.sub.on('message', (channel, msg) => {
this.handlers.get(channel)?.forEach(h => h(msg));
});
}
async broadcast(room, message) {
await this.pub.publish(room, JSON.stringify(message));
}
async onMessage(room, handler) {
if (!this.handlers.has(room)) {
this.handlers.set(room, new Set());
await this.sub.subscribe(room);
}
this.handlers.get(room).add(handler);
}
async close() {
await Promise.all([this.pub.quit(), this.sub.quit()]);
}
}
```
--------------------------------
### Example Usage of RouteParams Type
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md
Demonstrates how to use the RouteParams type to infer the shape of route parameters for different URL patterns.
```typescript
type Params = RouteParams<'/api/user/[userId]'>;
// Results in: { userId: string }
type Params2 = RouteParams<'/api/files/[...filepath]'>;
// Results in: { filepath: string[] }
type Params3 = RouteParams<'/api/docs/[[...slug]]'>;
// Results in: { slug?: string[] }
```
--------------------------------
### UPGRADE Handler Example
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/README.md
The main handler function exported from WebSocket routes. Receives the connected client, server, request, and route parameters. Can be async.
```typescript
export function UPGRADE(client, server, request, context) {
client.on('message', (msg) => {
// handle message
});
}
```
--------------------------------
### Verify next-ws Patches in GitHub Actions CI/CD
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md
Integrate next-ws verification and build steps into your CI/CD pipeline to ensure patches are applied correctly before deployment. This example uses GitHub Actions.
```yaml
# GitHub Actions example
- name: Verify patches
run: npx next-ws verify --ensure
- name: Build
run: npm run build
- name: Deploy
run: npm start
```
--------------------------------
### Verify and Auto-patch if Needed
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md
Verifies the Next.js patch status and automatically runs the patch command if the installation is not patched. This is useful for ensuring a patched environment.
```bash
npx next-ws verify --ensure
```
--------------------------------
### Redis Adapter Implementation
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md
An example implementation of the Adapter interface using Redis for pub/sub message broadcasting across multiple server instances. Ensure a Redis instance is accessible at the specified URL.
```typescript
import Redis from 'ioredis';
import type { Adapter } from 'next-ws/server';
class RedisAdapter implements Adapter {
private pub: Redis;
private sub: Redis;
private handlers = new Map void>>();
constructor(redisUrl: string = 'redis://localhost:6379') {
this.pub = new Redis(redisUrl);
this.sub = new Redis(redisUrl);
this.sub.on('message', (channel: string, msg: string) => {
const roomHandlers = this.handlers.get(channel);
if (!roomHandlers) return;
for (const handler of roomHandlers) {
handler(JSON.parse(msg));
}
});
}
async broadcast(room: string, message: unknown): Promise {
const messageStr = typeof message === 'string'
? message
: JSON.stringify(message);
await this.pub.publish(room, messageStr);
}
async onMessage(
room: string,
handler: (message: unknown) => void,
): Promise {
if (!this.handlers.has(room)) {
this.handlers.set(room, new Set());
await this.sub.subscribe(room);
}
this.handlers.get(room)?.add(handler);
}
async close(): Promise {
await Promise.all([this.pub.quit(), this.sub.quit()]);
}
}
```
--------------------------------
### Request Storage Example
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/README.md
AsyncLocalStorage wrapper providing access to request headers and cookies in async context without passing request through call stack.
```typescript
const storage = getRequestStorage();
const authHeader = storage.headers.get('authorization');
```
--------------------------------
### Run next-ws patch command
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md
Execute the CLI command to patch your local Next.js installation for WebSocket support. Use --yes to skip confirmation prompts.
```bash
next-ws patch [options]
```
--------------------------------
### RouteContext with Multiple Parameters
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md
Example showing how to access multiple string route parameters (e.g., 'orgId', 'teamId') from the RouteContext.params object.
```typescript
// Route: app/api/org/[orgId]/team/[teamId]/route.ts
export function UPGRADE(client, server, request, context) {
const orgId = context.params.orgId; // string
const teamId = context.params.teamId; // string
}
```
--------------------------------
### Project Documentation Coverage
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt
Details the extent of documentation for various aspects of the project, including the public API, handlers, configuration, CLI commands, and examples.
```APIDOC
## Project Documentation Coverage
### Description
Provides a high-level overview of the documentation's completeness for the /k0d13/next-ws project.
### Details
- Public API: 100% documented
- Handler types: 100% covered (current and deprecated)
- Configuration options: 100% covered
- CLI commands: 100% covered
- Examples: 6 complete, runnable implementations
- Architecture: Complete module analysis
```
--------------------------------
### useWebSocketServer()
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md
Gets or creates the WebSocket server instance. If an instance already exists, it's returned. Otherwise, a getter function is called to create and store a new instance.
```APIDOC
## useWebSocketServer()
### Description
Gets or creates the WebSocket server instance. If an instance already exists, returns it. Otherwise, calls the getter function to create one and stores it.
### Signature
```typescript
function useWebSocketServer(getter: () => import('ws').WebSocketServer): import('ws').WebSocketServer
```
### Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| getter | `() => import('ws').WebSocketServer` | yes | Function that creates and returns a new WebSocket server instance |
### Return Value
`import('ws').WebSocketServer` — The existing WebSocket server instance, or the result of calling `getter()` if none exists.
### Example
```typescript
import { WebSocketServer } from 'ws';
import { useWebSocketServer } from 'next-ws/server';
const wsServer = useWebSocketServer(() => new WebSocketServer({ noServer: true }));
```
```
--------------------------------
### Route Context Example
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/README.md
Type-safe object containing parsed dynamic route parameters. Type parameter is the route path for parameter inference.
```typescript
context: RouteContext<'/api/room/[roomId]'>
context.params.roomId // string
```
--------------------------------
### Initialize Request Storage
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md
Shows how to get or create the request storage using useRequestStorage, which takes a factory function to initialize a new AsyncLocalStorage if one doesn't exist. Requires importing from 'next-ws/server' and 'node:async_hooks'.
```typescript
import { useRequestStorage } from 'next-ws/server';
import { AsyncLocalStorage } from 'node:async_hooks';
const storage = useRequestStorage(() => new AsyncLocalStorage());
```
--------------------------------
### RouteContext with Optional Catch-All Parameter
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md
Example showing how to access an optional catch-all route parameter (e.g., 'slug') which can be an array of strings or undefined, from RouteContext.params.
```typescript
// Route: app/api/docs/[[...slug]]/route.ts
export function UPGRADE(client, server, request, context) {
const slug = context.params.slug; // string[] | undefined
if (slug) {
console.log(`Documentation page: ${slug.join('/')}`);
} else {
console.log('Home page');
}
}
```
--------------------------------
### Client-side WebSocket Connection
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
Connect to the WebSocket server from a Next.js client component and log received messages. This example sends 'hello' upon successful connection.
```typescript
'use client';
import { useEffect } from 'react';
export default function Home() {
useEffect(() => {
const ws = new WebSocket('ws://localhost:3000/api/ws');
ws.onmessage = (e) => console.log(e.data);
ws.onopen = () => ws.send('hello');
}, []);
return Check console
;
}
```
--------------------------------
### Dynamic Route Parameters in WebSocket Handler
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md
This example shows how to access dynamic route parameters within a WebSocket handler. The parameters are available in the `context.params` object.
```typescript
// app/api/room/[roomId]/ws/route.ts
export function GET() {
return new Response('Upgrade Required', { status: 426 });
}
export async function UPGRADE(client, server, request, context) {
const roomId = context.params.roomId as string;
console.log(`Client connected to room: ${roomId}`);
}
```
--------------------------------
### Use WebSocket Server Instance
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md
Gets or creates a WebSocket server instance. If one exists, it's returned. Otherwise, a new instance is created via the getter function and then stored.
```typescript
import { WebSocketServer } from 'ws';
import { useWebSocketServer } from 'next-ws/server';
const wsServer = useWebSocketServer(() => new WebSocketServer({ noServer: true }));
```
--------------------------------
### Use HTTP Server Instance
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md
Gets or creates an HTTP server instance. If an instance already exists, it's returned. Otherwise, a new instance is created using the provided getter function and then stored.
```typescript
import { Server } from 'node:http';
import { useHttpServer } from 'next-ws/server';
const server = useHttpServer(() => new Server());
```
--------------------------------
### Verify next-ws Patch
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md
Run this command to check if your local Next.js installation has been successfully patched by next-ws. It verifies the patch trace file and Next.js version.
```bash
next-ws verify [options]
```
--------------------------------
### ReadonlyRequestsCookies Usage Example
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-helpers.md
Illustrates the usage of `ReadonlyRequestsCookies`. Read methods like `get()` are functional, whereas attempting to modify cookies using `set()` will throw an error.
```typescript
const cookies = new ReadonlyRequestsCookies(headers);
console.log(cookies.get('sessionId')?.value); // Works
cookies.set('sessionId', 'abc123'); // Throws Error
```
--------------------------------
### ReadonlyHeaders Usage Example
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-helpers.md
Demonstrates how to use `ReadonlyHeaders`. Read methods like `get()` work normally, but attempting to modify the headers using `set()` will result in an error.
```typescript
const headers = new ReadonlyHeaders(originalHeaders);
console.log(headers.get('content-type')); // Works
headers.set('x-custom', 'value'); // Throws Error
```
--------------------------------
### Minimal Echo Server Route Handler
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
Set up a basic WebSocket endpoint in Next.js that echoes messages back to the client. This requires defining both GET and UPGRADE functions in your route handler.
```typescript
export function GET() {
const headers = new Headers();
headers.set('Connection', 'Upgrade');
headers.set('Upgrade', 'websocket');
return new Response('Upgrade Required', { status: 426, headers });
}
export function UPGRADE(client, server) {
client.on('message', (msg) => client.send(msg));
}
```
--------------------------------
### Use Adapter Instance
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md
Gets or creates the adapter instance. If an instance already exists, returns it. Otherwise, calls the getter function to create one and stores it. This is useful for lazy initialization of the adapter.
```typescript
import { useAdapter, type Adapter } from 'next-ws/server';
const adapter = useAdapter(() => new MyCustomAdapter());
```
--------------------------------
### Get WebSocket Server Instance
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md
Retrieves the globally stored WebSocket server instance. Use this to access an existing WebSocket server, for example, to check the number of connected clients.
```typescript
import { getWebSocketServer } from 'next-ws/server';
const wsServer = getWebSocketServer();
if (wsServer) {
console.log(`WebSocket server has ${wsServer.clients.size} clients`);
}
```
--------------------------------
### setupWebSocketServer()
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-setup.md
Initializes and attaches the WebSocket server to a Next.js HTTP server instance. This is the primary entry point for integrating next-ws with a Next.js app directory project.
```APIDOC
## setupWebSocketServer(nextServer, options?)
### Description
Initializes and attaches the WebSocket server to a Next.js HTTP server instance. This is the primary entry point for integrating next-ws with a Next.js app directory project.
### Method
Function
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Parameters
- **nextServer** (`NextNodeServer`) - Required - The Next.js Node server instance, typically obtained from `app.prepare()` when using a custom server
- **options** (`SetupOptions`) - Optional - Configuration options for setup, including optional adapter for multi-instance support
- **options.adapter** (`Adapter`) - Optional - Custom adapter implementation for broadcasting messages across multiple server instances via pub/sub
### Response
#### Success Response
`void` — The function attaches the WebSocket server directly to the provided HTTP server and does not return a value.
### Example
#### Basic Setup with Custom Server
```typescript
import { Server } from 'node:http';
import { parse } from 'node:url';
import next from 'next';
import { setupWebSocketServer } from 'next-ws/server';
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev, customServer: true });
const handle = app.getRequestHandler();
const httpServer = new Server();
app.prepare().then(() => {
httpServer
.on('request', async (req, res) => {
if (!req.url) return;
const parsedUrl = parse(req.url, true);
await handle(req, res, parsedUrl);
})
.listen(3000, () => {
// Setup WebSocket support after app is ready
setupWebSocketServer(app);
console.log('Server ready on http://localhost:3000');
});
});
```
#### Setup with Redis Adapter
```typescript
import { Server } from 'node:http';
import Redis from 'ioredis';
import { setupWebSocketServer, type Adapter } from 'next-ws/server';
class RedisAdapter implements Adapter {
private pub = new Redis(process.env.REDIS_URL);
private sub = new Redis(process.env.REDIS_URL);
private handlers = new Map void>>();
async broadcast(room: string, message: unknown): Promise {
await this.pub.publish(room, JSON.stringify(message));
}
async onMessage(
room: string,
handler: (message: unknown) => void,
): Promise {
if (!this.handlers.has(room)) {
this.handlers.set(room, new Set());
await this.sub.subscribe(room);
}
this.handlers.get(room)?.add(handler);
}
async close(): Promise {
await Promise.all([this.pub.quit(), this.sub.quit()]);
}
}
const httpServer = new Server();
const adapter = new RedisAdapter();
app.prepare().then(() => {
// Setup with multi-instance support
setupWebSocketServer(app, { adapter });
httpServer.listen(3000);
});
```
```
--------------------------------
### GET Handler
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/handlers.md
A required GET handler that responds with an error when the connection is not upgraded to WebSocket, adhering to HTTP protocol requirements.
```APIDOC
## GET /
### Description
A WebSocket API route must export a `GET` handler that responds with an error when the connection is not upgraded to WebSocket. This is required by HTTP protocol.
### Method
GET
### Endpoint
/
### Response
#### Success Response (426)
- **Headers**: `Connection: Upgrade`, `Upgrade: websocket`
- **Body**: `Upgrade Required`
### Request Example
```typescript
export function GET() {
const headers = new Headers();
headers.set('Connection', 'Upgrade');
headers.set('Upgrade', 'websocket');
return new Response('Upgrade Required', { status: 426, headers });
}
```
```
--------------------------------
### setupWebSocketServer() API
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
API for setting up the WebSocket server, with options for custom servers and adapters.
```APIDOC
### setupWebSocketServer()
```typescript
import { setupWebSocketServer } from 'next-ws/server';
// In custom server after app.prepare()
setupWebSocketServer(app);
// With adapter
setupWebSocketServer(app, { adapter: new RedisAdapter() });
```
```
--------------------------------
### View All next-ws Commands
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md
Displays a list of all available commands and their descriptions for the next-ws CLI.
```bash
npx next-ws --help
```
--------------------------------
### Implement GET Handler for WebSocket Route
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/handlers.md
Provides the required GET handler for a WebSocket API route. This handler returns a '426 Upgrade Required' response to enforce WebSocket protocol adherence.
```typescript
export function GET() {
const headers = new Headers();
headers.set('Connection', 'Upgrade');
headers.set('Upgrade', 'websocket');
return new Response('Upgrade Required', { status: 426, headers });
}
```
--------------------------------
### Imports for src/server/setup.ts
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/architecture.md
Shows the external and internal module imports required by the `setup.ts` file.
```typescript
// Imports: `ws`, `next/dist/build/output/log`, `next/dist/server/next-server`
// Internal imports: `adapter.ts`, `match.ts`, `module.ts`, `request.ts`, `persistent.ts`
// Exports: `setupWebSocketServer()`, `SetupOptions` interface
```
--------------------------------
### View Specific Command Help
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md
Shows detailed help information for a specific next-ws command, such as 'patch' or 'verify'.
```bash
npx next-ws patch --help
```
```bash
npx next-ws verify --help
```
--------------------------------
### Error Handling Pattern
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
Provides examples for handling errors during message processing and WebSocket connection errors.
```APIDOC
### Error Handling
```typescript
client.on('message', (data) => {
try {
// process message
} catch (err) {
const message = err instanceof Error ? err.message : 'Unknown error';
client.send(JSON.stringify({ error: message }));
}
});
client.on('error', (err) => {
console.error('WebSocket error:', err);
});
```
```
--------------------------------
### Initial Patching or Re-patching
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md
Run the patch command to apply necessary patches if Next.js has not been patched or if the trace file is missing. Alternatively, use 'verify --ensure' to auto-patch.
```bash
npx next-ws patch
```
```bash
npx next-ws verify --ensure
```
--------------------------------
### Broadcast to All Except Sender Pattern
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
Example of broadcasting a received message to all connected clients except the sender.
```APIDOC
### Broadcast to All Except Sender
```typescript
client.on('message', (data) => {
for (const other of server.clients) {
if (client !== other && other.readyState === other.OPEN) {
other.send(data);
}
}
});
```
```
--------------------------------
### Package.json Scripts for Development and Production
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/examples.md
These scripts configure the development server, production build, and multi-instance deployment using `concurrently`. The `prepare` script is essential for patching Next.js.
```json
{
"scripts": {
"dev": "node server.ts",
"build": "next build",
"start": "NODE_ENV=production node server.ts",
"start:multi": "concurrently 'INSTANCE_ID=1 node server.ts' 'INSTANCE_ID=2 PORT=3001 node server.ts'",
"prepare": "next-ws patch"
}
}
```
--------------------------------
### Get Request Storage
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md
Retrieves the stored request storage instance, if one has been set. This instance is typically an AsyncLocalStorage.
```typescript
import { getRequestStorage } from 'next-ws/server';
const storage = getRequestStorage();
if (storage) {
console.log('Request storage is available');
}
```
--------------------------------
### Get Adapter Instance
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md
Retrieves the globally stored adapter instance. Use this to access the configured adapter for multi-instance scenarios.
```typescript
import { getAdapter } from 'next-ws/server';
const adapter = getAdapter();
if (adapter) {
console.log('Multi-instance adapter is configured');
}
```
--------------------------------
### Project Structure
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/architecture.md
The project is organized into distinct modules for CLI, client-side helpers, core server implementation, and CLI commands.
```tree
src/
├── cli.ts # CLI entry point
├── client/ # Client-side React helpers (deprecated)
│ ├── context.tsx
│ └── index.ts
├── server/ # Core server implementation
│ ├── setup.ts # Main WebSocket setup function
│ ├── persistent.ts # Global singleton storage
│ ├── helpers/
│ │ ├── adapter.ts # Multi-instance adapter interface
│ │ ├── socket.ts # Handler type definitions
│ │ ├── module.ts # Route module loading
│ │ ├── request.ts # Request conversion utilities
│ │ ├── match.ts # Route matching logic
│ │ └── store.ts # Request storage API
│ └── index.ts # Server module exports
└── commands/ # CLI implementation
├── index.ts # Command group definition
├── patch.ts # Patch command
├── verify.ts # Verify command
└── helpers/ # CLI utilities
├── define.ts # Command definition helpers
├── console.ts # Console utilities
└── semver.ts # Version utilities
```
--------------------------------
### Usage Recommendations - Learning Path
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt
Suggests a learning path for users to progressively understand the project's features and APIs.
```APIDOC
## Usage Recommendations: LEARNING PATH
### Description
Recommends a sequence for learning the project's concepts and APIs.
### Recommended Order
1. quick-start.md (overview)
2. examples.md (usage patterns)
3. api-reference/handlers.md (handler API)
4. api-reference/server-setup.md (setup)
5. types.md (type details)
```
--------------------------------
### Import Server and Client APIs
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md
Demonstrates the correct import paths for server-side and client-side APIs provided by the next-ws library. Note the deprecated client API.
```typescript
// Server API
import { setupWebSocketServer } from 'next-ws/server';
import type { Adapter, RouteContext } from 'next-ws/server';
// Client API (deprecated)
import { WebSocketProvider, useWebSocket } from 'next-ws/client';
// Types
import type { UpgradeHandler } from 'next-ws/server';
```
--------------------------------
### Get HTTP Server Instance
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md
Retrieves the globally stored HTTP server instance. Use this when you need to access an existing HTTP server.
```typescript
import { getHttpServer } from 'next-ws/server';
const server = getHttpServer();
if (server) {
console.log('HTTP server is available');
}
```
--------------------------------
### Adapter
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md
Interface for multi-instance WebSocket deployments, enabling message broadcasting across multiple server instances via pub/sub.
```APIDOC
## Interface: Adapter
### Description
Interface for multi-instance WebSocket deployments. Enables message broadcasting across multiple server instances via pub/sub.
### Methods
#### broadcast(room: string, message: unknown): Promise
Broadcasts a message to all instances subscribed to the specified room.
**Parameters:**
- **room** (string): Room identifier, typically the route pathname (e.g., `/api/chat`)
- **message** (unknown): Message to broadcast; will be JSON stringified if needed
#### onMessage(room: string, handler: (message: unknown) => void): void | Promise
Subscribes to messages for a specific room.
**Parameters:**
- **room** (string): Room identifier to subscribe to
- **handler** (`(message: unknown) => void`): Callback invoked when messages arrive for this room
#### close(): Promise
Cleans up adapter resources: closes connections, unsubscribes from channels, and releases all stored references.
```
--------------------------------
### getHttpServer()
Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md
Retrieves the stored HTTP server instance. Returns the instance if set, otherwise undefined.
```APIDOC
## getHttpServer()
### Description
Retrieves the stored HTTP server instance, if one has been set.
### Signature
```typescript
function getHttpServer(): import('node:http').Server | undefined
```
### Return Value
`import('node:http').Server | undefined` — The stored HTTP server instance, or `undefined` if not yet set.
### Example
```typescript
import { getHttpServer } from 'next-ws/server';
const server = getHttpServer();
if (server) {
console.log('HTTP server is available');
}
```
```