{"id":24111468,"url":"https://github.com/nartix/next-middleware-chain","last_synced_at":"2026-02-11T16:02:29.144Z","repository":{"id":269001041,"uuid":"906105735","full_name":"nartix/next-middleware-chain","owner":"nartix","description":"A lightweight middleware chainer for NextJS 14/15","archived":false,"fork":false,"pushed_at":"2025-01-31T11:02:25.000Z","size":21,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-14T20:56:28.092Z","etag":null,"topics":["middleware","nextjs"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@nartix/next-middleware-chain","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nartix.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-20T07:14:15.000Z","updated_at":"2025-01-31T11:00:39.000Z","dependencies_parsed_at":"2024-12-20T08:33:00.770Z","dependency_job_id":"0b8764d0-28d5-47e1-bc45-a0316c978a38","html_url":"https://github.com/nartix/next-middleware-chain","commit_stats":null,"previous_names":["nartix/next-middleware-chain"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nartix%2Fnext-middleware-chain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nartix%2Fnext-middleware-chain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nartix%2Fnext-middleware-chain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nartix%2Fnext-middleware-chain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nartix","download_url":"https://codeload.github.com/nartix/next-middleware-chain/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253928431,"owners_count":21985793,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["middleware","nextjs"],"created_at":"2025-01-11T02:34:23.338Z","updated_at":"2026-02-11T16:02:29.115Z","avatar_url":"https://github.com/nartix.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# next-middleware-chain\n\nA lightweight utility for composing Next.js middleware functions in a simple and maintainable way. Using a chain-of-responsibility style, you can easily combine multiple middleware steps into a single pipeline.\n\n## Installation\n\n```bash\nnpm install @nartix/next-middleware-chain\n```\n\nor\n\n```bash\nyarn add @nartix/next-middleware-chain\n```\n\n## Overview\n\nThis package provides a function that takes multiple middleware handlers and executes them in sequence until one of them decides to stop the chain or until all have processed the request.\n\n**Key Features:**\n\n- **Modular:** Build complex logic from simple, single-purpose middleware functions.\n- **Flexible:** Any middleware can terminate the chain early, returning its final response.\n- **Maintainable:** Clear and predictable middleware flows.\n\n## Basic Usage\n\n### Defining Your Middlewares\n\nIn this new approach, each **middleware** is defined as a **factory** function. A **middleware factory** takes a `next` function and returns an async function that will receive:\n\n- **`req`:** The `NextRequest`  \n- **`event`:** The `NextFetchEvent`  \n- **`incomingResponse` (optional):** A `NextResponse` passed forward from previous factories in the chain (if any)\n\nTo continue the chain, call `next(req, event, response)`. To short-circuit, simply return a final `NextResponse` or a native `Response` (e.g., for redirects or errors).\n\n```typescript\nimport { NextResponse } from 'next/server';\nimport { MiddlewareFactory } from '@nartix/next-middleware-chain'; // or your package name\n\nexport const logRequestTimeFactory: MiddlewareFactory = (next) =\u003e {\n  return async (req, event, incomingResponse) =\u003e {\n    console.log('Request received at:', Date.now());\n    // Continue to the next middleware\n    return next(req, event, incomingResponse);\n  };\n};\n\nexport const addHeaderA: MiddlewareFactory = (next) =\u003e {\n  return async (req, event, incomingResponse) =\u003e {\n    // Use existing response if available, otherwise create a new one\n    const response = incomingResponse ?? NextResponse.next();\n    response.headers.set('X-Header-A', 'ValueA');\n    // Continue the chain\n    return next(req, event, response);\n  };\n};\n```\n\n### Composing Middlewares\n\nUse `createMiddlewareChain` to create a composed handler:\n\n```typescript\n// middleware.ts\nimport { logRequestTimeFactory } from './logRequestTimeFactory';\nimport { addHeaderAFactory } from './addHeaderAFactory';\n\nconst factories = [\n  logRequestTimeFactory,\n  addHeaderAFactory\n  // ...add as many middleware functions as you like\n  ];\n\nexport default createMiddlewareChain(factories);\n```\n\n## Advanced Usage\n\nYou might have a more complex scenario where you conditionally alter headers or short-circuit early based on certain conditions. For example:\n\n```typescript\n// Example: A middleware that checks for an auth token.\nexport const checkAuth: MiddlewareFactory = (next) =\u003e {\n  return async (req: NextRequest, event: NextFetchEvent, incomingResponse?: NextResponse) =\u003e {\n    const token = req.headers.get('Authorization');\n    if (!token) {\n      // Return a 401 immediately, short-circuiting the chain\n      return new Response('Unauthorized', { status: 401 });\n    }\n\n    // Otherwise, continue to the next middleware.\n    // If we received a shared response, reuse it; otherwise create a new one\n    return next(req, event, incomingResponse ?? NextResponse.next());\n  };\n};\n\n// Example: A middleware that adds a custom header to the response.\nexport const addCustomHeader: MiddlewareFactory = (next) =\u003e {\n  return async (req: NextRequest, event: NextFetchEvent, incomingResponse?: NextResponse) =\u003e {\n    const response = incomingResponse ?? NextResponse.next();\n    response.headers.set('X-Custom-Header', 'MyValue');\n    return next(req, event, response);\n  };\n};\n\n// Example: Calling All Subsequent Factories, Then Editing the Final Response\nexport const addFinalHeader: MiddlewareFactory = (next) =\u003e {\n  return async (req, event, incomingResponse) =\u003e {\n    // Let other factories run first\n    const result = await next(req, event, incomingResponse ?? NextResponse.next());\n\n    // If we got a NextResponse back, add a final header\n    if (result instanceof NextResponse) {\n      result.headers.set('X-Final-Header', 'FinalValue');\n      return result;\n    }\n\n    // If it's a plain Response or no return, just pass it along\n    return result;\n  };\n};\n```\n\n**Happy coding!** If you have questions, feel free to open an issue or submit a pull request.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnartix%2Fnext-middleware-chain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnartix%2Fnext-middleware-chain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnartix%2Fnext-middleware-chain/lists"}