Next.js Connect Router

1.0.0 · active · verified Wed Apr 22

next-connect is a promise-based routing and middleware layer designed specifically for Next.js applications, supporting various environments including API Routes, Edge API Routes, Middleware, App Router Route Handlers, and `getServerSideProps`. Currently at stable version 1.0.0, the library has historically followed an active release cadence, with pre-releases leading up to major versions. Its key differentiators include asynchronous middleware support, a lightweight footprint suitable for serverless environments, and significantly faster performance compared to traditional Express.js setups. It also offers robust TypeScript support and handles asynchronous handlers with integrated error catching, providing a flexible and efficient alternative for managing server-side logic in Next.js projects.

Common errors

Warnings

Install

Imports

Quickstart

This example demonstrates creating an API route with `next-connect`, handling GET and PUT requests, implementing asynchronous middleware for logging, and setting up global error handling for unmatched routes and exceptions.

import type { NextApiRequest, NextApiResponse } from "next";
import { createRouter } from "next-connect";

// Mock dependencies for a runnable example
const getUser = (id: string) => ({ id, name: `User ${id}`, email: `${id}@example.com` });
const updateUser = async (data: any) => ({ ...data, updatedAt: new Date().toISOString() });
class ForbiddenError extends Error {
  statusCode: number;
  constructor(message: string) {
    super(message);
    this.name = 'ForbiddenError';
    this.statusCode = 403;
  }
}

const router = createRouter<NextApiRequest, NextApiResponse>();

router
  .use(async (req, res, next) => {
    const start = Date.now();
    // Simulate authentication or logging
    console.log(`Incoming request to ${req.url}`);
    await next(); // call next in chain
    const end = Date.now();
    console.log(`Request to ${req.url} took ${end - start}ms`);
  })
  .get((req, res) => {
    const { id } = req.query;
    if (typeof id !== 'string') {
      res.status(400).json({ message: 'Invalid user ID' });
      return;
    }
    const user = getUser(id);
    res.json({ user });
  })
  .put(async (req, res) => {
    // Simulate user context (e.g., from session/token)
    const currentUser = { id: 'currentUserId123' }; // Mock current user
    const { id } = req.query;
    if (typeof id !== 'string') {
      throw new Error('Invalid user ID for update');
    }

    // Example authorization check
    if (currentUser.id !== id) {
      throw new ForbiddenError("You can't update other user's profile");
    }
    const updatedUser = await updateUser({ id, ...req.body });
    res.json({ user: updatedUser });
  });

export default router.handler({
  onError: (err, req, res) => {
    console.error(err.stack); // Log the error for debugging
    const statusCode = (err as ForbiddenError).statusCode || 500;
    res.status(statusCode).end(err.message || "Something broke!");
  },
  onNoMatch: (req, res) => {
    res.status(404).end(`Route ${req.method} ${req.url} not found`);
  },
});

view raw JSON →