{"_id":"@cxnpl/next-app-middleware","_rev":"11-2b250e861451b5a8262175739f6bbd39","name":"@cxnpl/next-app-middleware","dist-tags":{"latest":"0.0.11"},"versions":{"0.0.5":{"name":"@cxnpl/next-app-middleware","version":"0.0.5","keywords":[],"author":"","license":"ISC","_id":"@cxnpl/next-app-middleware@0.0.5","maintainers":[{"name":"macku","email":"npm@maciejadamczak.net"}],"homepage":"https://github.com/cxnpl-forks/next-app-middleware#readme","bugs":{"url":"https://github.com/cxnpl-forks/next-app-middleware/issues"},"dist":{"shasum":"ec56cdf12684b31ad8cd668700e2866a840b3d1a","tarball":"https://registry.npmjs.org/@cxnpl/next-app-middleware/-/next-app-middleware-0.0.5.tgz","fileCount":10,"integrity":"sha512-rI5NiS3LHJ8vRzTwY6VGr+Wh5MCm+DWbqOF6yDWMfm2l0CwlBkh8MGjzbSzTomE8gRr9iFtS06wO4gYdpbVIeg==","signatures":[{"sig":"MEUCIQCpD7iaJAhdYsblycUoNUILgRJPMMppeEXiavEVke7oaAIgCIlLwIQYZf/Dg8jFeTx5j9RESJ0Wpuqr/BYVaELdvM4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":25557},"main":"index.js","types":"index.d.ts","gitHead":"d024bef810b41c8beaf07da5b4e08be7700c6891","private":false,"scripts":{"dev":"concurrently \"pnpm run build:swc --watch\" \"pnpm run build:tsc --watch\"","build":"concurrently \"pnpm run build:swc\" \"pnpm run build:tsc\"","release":"turbo-module publish","build:swc":"swc src -d ./ -s -C module.type=commonjs","build:tsc":"tsc --emitDeclarationOnly"},"_npmUser":{"name":"macku","email":"npm@maciejadamczak.net"},"repository":{"url":"git+https://github.com/cxnpl-forks/next-app-middleware.git","type":"git"},"_npmVersion":"10.1.0","description":"# [!IMPORTANT] # This project is a fork of the [next-app-middleware](https://github.com/whopio/next-app-middleware) project.","directories":{},"_nodeVersion":"20.9.0","dependencies":{"@cxnpl/next-app-middleware-codegen":"0.0.5","@cxnpl/next-app-middleware-runtime":"0.0.5"},"_hasShrinkwrap":false,"devDependencies":{"next":"14.1.1","@swc/cli":"^0.1.57","tsconfig":"workspace:0.0.0","@swc/core":"^1.3.21","typescript":"^4.9.3","concurrently":"^7.6.0","@whop-sdk/turbo-module":"0.0.4-canary.1"},"peerDependencies":{"next":"^13.2 || ^14"},"_npmOperationalInternal":{"tmp":"tmp/next-app-middleware_0.0.5_1718373438979_0.9558543416338567","host":"s3://npm-registry-packages"}},"0.0.6":{"name":"@cxnpl/next-app-middleware","version":"0.0.6","keywords":[],"author":"","license":"ISC","_id":"@cxnpl/next-app-middleware@0.0.6","maintainers":[{"name":"macku","email":"npm@maciejadamczak.net"}],"homepage":"https://github.com/cxnpl-forks/next-app-middleware#readme","bugs":{"url":"https://github.com/cxnpl-forks/next-app-middleware/issues"},"dist":{"shasum":"6f040b482145ce1a2a830e3a46e3a7fc0832f5dd","tarball":"https://registry.npmjs.org/@cxnpl/next-app-middleware/-/next-app-middleware-0.0.6.tgz","fileCount":10,"integrity":"sha512-OG3i2qZfw7WnFq27CEtRLvQ+8vkQbXLgSHLcKmwKouQVVdWHtERctyAIUu671vrgkBKJNJ9yzgfs1Eb6TpOAsQ==","signatures":[{"sig":"MEQCIFAH88zR3j6JXX8xUn6IJASl2Q9uv1na31BnpRLuvnoIAiATKszo9GCMgDoTNONzkxB/S5f+E5/HVaiIlDAlrzyZ8A==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":25546},"main":"index.js","_from":"file:cxnpl-next-app-middleware-0.0.6.tgz","types":"index.d.ts","private":false,"scripts":{"dev":"concurrently \"pnpm run build:swc --watch\" \"pnpm run build:tsc --watch\"","build":"concurrently \"pnpm run build:swc\" \"pnpm run build:tsc\"","release":"turbo-module publish","build:swc":"swc src -d ./ -s -C module.type=commonjs","build:tsc":"tsc --emitDeclarationOnly"},"_npmUser":{"name":"macku","email":"npm@maciejadamczak.net"},"_resolved":"/private/var/folders/49/80pc51vj4wvdl58mmvfqnh480000gn/T/0322710b0280a8182543e3eda97224dc/cxnpl-next-app-middleware-0.0.6.tgz","_integrity":"sha512-OG3i2qZfw7WnFq27CEtRLvQ+8vkQbXLgSHLcKmwKouQVVdWHtERctyAIUu671vrgkBKJNJ9yzgfs1Eb6TpOAsQ==","repository":{"url":"git+https://github.com/cxnpl-forks/next-app-middleware.git","type":"git"},"_npmVersion":"10.1.0","description":"> [!IMPORTANT] > This project is a fork of the [next-app-middleware](https://github.com/whopio/next-app-middleware) project.","directories":{},"_nodeVersion":"20.9.0","dependencies":{"@cxnpl/next-app-middleware-codegen":"0.0.6","@cxnpl/next-app-middleware-runtime":"0.0.6"},"_hasShrinkwrap":false,"devDependencies":{"next":"14.1.1","@swc/cli":"^0.1.57","tsconfig":"0.0.0","@swc/core":"^1.3.21","typescript":"^4.9.3","concurrently":"^7.6.0","@whop-sdk/turbo-module":"0.0.4-canary.1"},"peerDependencies":{"next":"^13.2 || ^14"},"_npmOperationalInternal":{"tmp":"tmp/next-app-middleware_0.0.6_1718590961386_0.37355703811242447","host":"s3://npm-registry-packages"}},"0.0.7":{"name":"@cxnpl/next-app-middleware","version":"0.0.7","keywords":[],"author":"","license":"ISC","_id":"@cxnpl/next-app-middleware@0.0.7","maintainers":[{"name":"macku","email":"npm@maciejadamczak.net"}],"homepage":"https://github.com/cxnpl-forks/next-app-middleware#readme","bugs":{"url":"https://github.com/cxnpl-forks/next-app-middleware/issues"},"dist":{"shasum":"040314d285362630350dd73e004d5740a076e047","tarball":"https://registry.npmjs.org/@cxnpl/next-app-middleware/-/next-app-middleware-0.0.7.tgz","fileCount":10,"integrity":"sha512-2K3BjCBblAl5EAZQvNL+U3i1eFzu5ZV4Sk+7Z5zx8oNOV6dchy7Nuy5Z6YhqKRYD8VMSZgiRX2rfykOPcOYrqw==","signatures":[{"sig":"MEUCIGmAT3vsQ6+nk094k0hGmoaX15Q4ew/kZGWuV+/HpihBAiEAqnwBD7wNJErX16gbLRMK/zMJr354HdVfcVAtOXHJ1vI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":25719},"main":"index.js","_from":"file:cxnpl-next-app-middleware-0.0.7.tgz","types":"index.d.ts","private":false,"scripts":{"dev":"concurrently \"pnpm run build:swc --watch\" \"pnpm run build:tsc --watch\"","build":"concurrently \"pnpm run build:swc\" \"pnpm run build:tsc\"","release":"turbo-module publish","build:swc":"swc src -d ./ -s -C module.type=commonjs","build:tsc":"tsc --emitDeclarationOnly"},"_npmUser":{"name":"macku","email":"npm@maciejadamczak.net"},"_resolved":"/tmp/93d1bcf6098279d7bc0c3a32dc77dbd9/cxnpl-next-app-middleware-0.0.7.tgz","_integrity":"sha512-2K3BjCBblAl5EAZQvNL+U3i1eFzu5ZV4Sk+7Z5zx8oNOV6dchy7Nuy5Z6YhqKRYD8VMSZgiRX2rfykOPcOYrqw==","repository":{"url":"git+https://github.com/cxnpl-forks/next-app-middleware.git","type":"git"},"_npmVersion":"10.7.0","description":"> [!IMPORTANT] > This project is a fork of the [next-app-middleware](https://github.com/whopio/next-app-middleware) project.","directories":{},"_nodeVersion":"20.14.0","dependencies":{"@cxnpl/next-app-middleware-codegen":"0.0.7","@cxnpl/next-app-middleware-runtime":"0.0.7"},"_hasShrinkwrap":false,"devDependencies":{"next":"14.1.1","@swc/cli":"^0.1.57","tsconfig":"0.0.0","@swc/core":"^1.3.21","typescript":"^4.9.3","concurrently":"^7.6.0","@whop-sdk/turbo-module":"0.0.4-canary.1"},"peerDependencies":{"next":"^13.2 || ^14"},"_npmOperationalInternal":{"tmp":"tmp/next-app-middleware_0.0.7_1718595449746_0.795436665706112","host":"s3://npm-registry-packages"}},"0.0.8":{"name":"@cxnpl/next-app-middleware","version":"0.0.8","keywords":[],"author":"","license":"ISC","_id":"@cxnpl/next-app-middleware@0.0.8","maintainers":[{"name":"macku","email":"npm@maciejadamczak.net"}],"homepage":"https://github.com/cxnpl-forks/next-app-middleware#readme","bugs":{"url":"https://github.com/cxnpl-forks/next-app-middleware/issues"},"dist":{"shasum":"ef6719f5f04e55de5cb9a6c7bf0637907acf543c","tarball":"https://registry.npmjs.org/@cxnpl/next-app-middleware/-/next-app-middleware-0.0.8.tgz","fileCount":10,"integrity":"sha512-yJ73/BfdRX7jKd7Uf1eQltkjsvR+tsK18L+zBJikAi5sSEnNN3PbOZNxT2rZsdQ3pqXCpSMerTF8BDOuDcfsLw==","signatures":[{"sig":"MEUCIQDrabxpNy0UHozBOJslhKdZuET1gZrib4rXmG7TaXyvPwIge6zUC2vJfrZA63kuneXekiepKOn/prGLeFP/LHmJF9I=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":25719},"main":"index.js","_from":"file:cxnpl-next-app-middleware-0.0.8.tgz","types":"index.d.ts","private":false,"scripts":{"dev":"concurrently \"pnpm run build:swc --watch\" \"pnpm run build:tsc --watch\"","build":"concurrently \"pnpm run build:swc\" \"pnpm run build:tsc\"","release":"turbo-module publish","build:swc":"swc src -d ./ -s -C module.type=commonjs","build:tsc":"tsc --emitDeclarationOnly"},"_npmUser":{"name":"macku","email":"npm@maciejadamczak.net"},"_resolved":"/tmp/b948cf290c94fc5c571d8089770abc81/cxnpl-next-app-middleware-0.0.8.tgz","_integrity":"sha512-yJ73/BfdRX7jKd7Uf1eQltkjsvR+tsK18L+zBJikAi5sSEnNN3PbOZNxT2rZsdQ3pqXCpSMerTF8BDOuDcfsLw==","repository":{"url":"git+https://github.com/cxnpl-forks/next-app-middleware.git","type":"git"},"_npmVersion":"10.8.2","description":"> [!IMPORTANT] > This project is a fork of the [next-app-middleware](https://github.com/whopio/next-app-middleware) project.","directories":{},"_nodeVersion":"20.17.0","dependencies":{"@cxnpl/next-app-middleware-codegen":"0.0.8","@cxnpl/next-app-middleware-runtime":"0.0.8"},"_hasShrinkwrap":false,"devDependencies":{"next":"14.1.1","@swc/cli":"^0.1.57","tsconfig":"0.0.0","@swc/core":"^1.3.21","typescript":"^4.9.3","concurrently":"^7.6.0","@whop-sdk/turbo-module":"0.0.4-canary.1"},"peerDependencies":{"next":"^13.2 || ^14"},"_npmOperationalInternal":{"tmp":"tmp/next-app-middleware_0.0.8_1726056637235_0.188333395432275","host":"s3://npm-registry-packages"}},"0.0.9":{"name":"@cxnpl/next-app-middleware","version":"0.0.9","keywords":[],"author":"","license":"ISC","_id":"@cxnpl/next-app-middleware@0.0.9","maintainers":[{"name":"macku","email":"npm@maciejadamczak.net"}],"homepage":"https://github.com/cxnpl-forks/next-app-middleware#readme","bugs":{"url":"https://github.com/cxnpl-forks/next-app-middleware/issues"},"dist":{"shasum":"476045eff56f1c0ada64c90b7353a1609e598338","tarball":"https://registry.npmjs.org/@cxnpl/next-app-middleware/-/next-app-middleware-0.0.9.tgz","fileCount":10,"integrity":"sha512-BOYF2W72Spcrrerz079duPjvBXNO7lqQmZkJSwFgf1ui5E5s7cb3T/89fAlQm38cop7K3CAmQOn/xMxS8Iv0PQ==","signatures":[{"sig":"MEUCIDYI++hMinZdYihU1x4t+zAt1KxLjwauint3n8KE2vfTAiEA/QyBCjzTlB9Ae2Oh1yZB73PTn+YxNYiQsE7MqeN9ueQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":25877},"main":"index.js","_from":"file:cxnpl-next-app-middleware-0.0.9.tgz","types":"index.d.ts","private":false,"scripts":{"dev":"concurrently \"pnpm run build:swc --watch\" \"pnpm run build:tsc --watch\"","build":"concurrently \"pnpm run build:swc\" \"pnpm run build:tsc\"","release":"turbo-module publish","build:swc":"swc src -d ./ -s -C module.type=commonjs","build:tsc":"tsc --emitDeclarationOnly"},"_npmUser":{"name":"macku","email":"npm@maciejadamczak.net"},"_resolved":"/private/var/folders/49/80pc51vj4wvdl58mmvfqnh480000gn/T/046a9589f1b436298dc4f39248d8a743/cxnpl-next-app-middleware-0.0.9.tgz","_integrity":"sha512-BOYF2W72Spcrrerz079duPjvBXNO7lqQmZkJSwFgf1ui5E5s7cb3T/89fAlQm38cop7K3CAmQOn/xMxS8Iv0PQ==","repository":{"url":"git+https://github.com/cxnpl-forks/next-app-middleware.git","type":"git"},"_npmVersion":"10.9.3","description":"> [!IMPORTANT] > This project is a fork of the [next-app-middleware](https://github.com/whopio/next-app-middleware) project.","directories":{},"_nodeVersion":"22.20.0","dependencies":{"@cxnpl/next-app-middleware-codegen":"0.0.9","@cxnpl/next-app-middleware-runtime":"0.0.9"},"_hasShrinkwrap":false,"devDependencies":{"next":"~15.5.0","@swc/cli":"^0.1.57","tsconfig":"0.0.0","@swc/core":"^1.3.21","typescript":"^4.9.3","concurrently":"^7.6.0","@whop-sdk/turbo-module":"0.0.7"},"peerDependencies":{"next":"^15"},"_npmOperationalInternal":{"tmp":"tmp/next-app-middleware_0.0.9_1771281824066_0.042698157086419775","host":"s3://npm-registry-packages-npm-production"}},"0.0.11":{"name":"@cxnpl/next-app-middleware","version":"0.0.11","description":"> [!IMPORTANT] > This project is a fork of the [next-app-middleware](https://github.com/whopio/next-app-middleware) project.","private":false,"main":"index.js","types":"index.d.ts","repository":{"type":"git","url":"git+https://github.com/cxnpl-forks/next-app-middleware.git"},"bugs":{"url":"https://github.com/cxnpl-forks/next-app-middleware/issues"},"keywords":[],"author":"","license":"ISC","devDependencies":{"@swc/cli":"^0.1.57","@swc/core":"^1.3.21","@whop-sdk/turbo-module":"0.0.4-canary.1","concurrently":"^7.6.0","next":"~15.5.0","tsconfig":"0.0.0","typescript":"^4.9.3"},"peerDependencies":{"next":"^15"},"dependencies":{"@cxnpl/next-app-middleware-codegen":"0.0.11","@cxnpl/next-app-middleware-runtime":"0.0.11"},"scripts":{"build":"concurrently \"pnpm run build:swc\" \"pnpm run build:tsc\"","build:swc":"swc src -d ./ -s -C module.type=commonjs","build:tsc":"tsc --emitDeclarationOnly","dev":"concurrently \"pnpm run build:swc --watch\" \"pnpm run build:tsc --watch\"","release":"turbo-module publish"},"_id":"@cxnpl/next-app-middleware@0.0.11","homepage":"https://github.com/cxnpl-forks/next-app-middleware#readme","_integrity":"sha512-gRrda7jnJ0IZfHulw3e1SGQL2dFMma8NlDnTFGA1XDzeZg4DWqKaLL2r0srvibTqAapaxe137xx203fgTzlD8w==","_resolved":"/private/var/folders/dk/ksq_r34d5y5g1xk6fkmt765c0000gn/T/9f147c0df3814304e2664954cf8d175b/cxnpl-next-app-middleware-0.0.11.tgz","_from":"file:cxnpl-next-app-middleware-0.0.11.tgz","_nodeVersion":"22.20.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-gRrda7jnJ0IZfHulw3e1SGQL2dFMma8NlDnTFGA1XDzeZg4DWqKaLL2r0srvibTqAapaxe137xx203fgTzlD8w==","shasum":"c4f28525069baff072f6c61476f879a0e57ca968","tarball":"https://registry.npmjs.org/@cxnpl/next-app-middleware/-/next-app-middleware-0.0.11.tgz","fileCount":10,"unpackedSize":29470,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD5f39WZL529DCoucOYucezT7FKs0IjEIfa3+QNqmWnzwIgGTHaUIuYcU3euK+LfWMwIoJqsn2pYjQspO7+33YChqw="}]},"_npmUser":{"name":"andrew-cxnpl","email":"andrewc@cxnpl.com"},"directories":{},"maintainers":[{"name":"sdcxnpl","email":"santiagod@cxnpl.com"},{"name":"daniel-cxnpl","email":"duc@cxnpl.com"},{"name":"macku","email":"npm@maciejadamczak.net"},{"name":"andrew-cxnpl","email":"andrewc@cxnpl.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/next-app-middleware_0.0.11_1782286185556_0.8659119518611074"},"_hasShrinkwrap":false}},"time":{"created":"2024-06-14T13:57:18.903Z","modified":"2026-06-24T07:29:45.874Z","0.0.5":"2024-06-14T13:57:19.142Z","0.0.6":"2024-06-17T02:22:41.620Z","0.0.7":"2024-06-17T03:37:29.904Z","0.0.8":"2024-09-11T12:10:37.376Z","0.0.9":"2026-02-16T22:43:44.229Z","0.0.10":"2026-06-24T05:39:43.286Z","0.0.11":"2026-06-24T07:29:45.694Z"},"bugs":{"url":"https://github.com/cxnpl-forks/next-app-middleware/issues"},"license":"ISC","homepage":"https://github.com/cxnpl-forks/next-app-middleware#readme","keywords":[],"repository":{"type":"git","url":"git+https://github.com/cxnpl-forks/next-app-middleware.git"},"description":"> [!IMPORTANT] > This project is a fork of the [next-app-middleware](https://github.com/whopio/next-app-middleware) project.","maintainers":[{"name":"sdcxnpl","email":"santiagod@cxnpl.com"},{"name":"daniel-cxnpl","email":"duc@cxnpl.com"},{"name":"macku","email":"npm@maciejadamczak.net"},{"name":"andrew-cxnpl","email":"andrewc@cxnpl.com"}],"readme":"# @cxnpl/next-app-middleware\n\n> [!IMPORTANT]\n> This project is a fork of the [next-app-middleware](https://github.com/whopio/next-app-middleware) project.\n\nnext.js uses your filesystem structure to route requests to pages, why should you have to manually route middleware?\n\nSkip the task of matching request paths to conditionally run code in your middleware - this extension allows you to locate your middleware code directly inside the app directory and only run it when it matters.\n\n### before\n\n```\n/app/\n - /(authenticated)\n   - /page1/page.js\n   - /page2/page.js\n - /(unauthenticated)\n   - /login/page.js\n - /page3/page.js\n - /page4/page.js\n - /layout.js\n/middleware.js\n```\n\n```ts\n// middleware.js\nimport isAuthenticated from \"@/lib/isAuthenticated\";\nimport { NextResponse } from \"next/server\";\n\nconst middleware = (req) => {\n  // here every page that should be only accessed by authenticated users needs to be listed\n  // and manually kept in sync with the project structure\n  if (req.nextUrl.pathname === \"/page1\" || req.nextUrl.pathname === \"/page2\") {\n    if (!(await isAuthenticated(req))) {\n      return NextResponse.redirect(\"/login\");\n    }\n  } else if (req.nextUrl.pathname === \"/login\") {\n    if (await isAuthenticated(req)) {\n      return NextResponse.redirect(\"/page1\");\n    }\n  }\n  return NextResponse.next();\n};\n\nexport default middleare;\n```\n\n### after\n\n```\n/app/\n - /(authenticated)\n   - /page1/page.js\n   - /page2/page.js\n   - middleware.js\n - /(unauthenticated)\n   - /login/page.js\n   - middleware.js\n - /page3/page.js\n - /page4/page.js\n - /layout.js\n```\n\n```ts\n// app/(authenticated)/middleware.js\nimport isAuthenticated from \"@/lib/isAuthenticated\";\n\nconst middleware = async (req) => {\n  if (!(await isAuthenticated(req)))\n    return {\n      redirect: \"/login\",\n    };\n};\n\nexport default middleware;\n\n// app/(unauthenticated)/middleware.js\nimport isAuthenticated from \"@/lib/isAuthenticated\";\n\nconst middleware = async (req) => {\n  if (await isAuthenticated(req))\n    return {\n      redirect: \"/page1\",\n    };\n};\n\nexport default middleware;\n```\n\nIn this setup the middleware will only run if the request path is matching a page in the `(authenticated)` group segment.\n\n## setup\n\n### install\n\npnpm\n\n```\npnpm install @cxnpl/next-app-middleware --save-dev\n```\n\nyarn\n\n```\nyarn add @cxnpl/next-app-middleware --dev\n```\n\nnpm\n\n```\nnpm install @cxnpl/next-app-middleware --save-dev\n```\n\n### clean up current middleware and git working tree\n\n- delete your current middleware (or change the name if you want to keep it)\n- commit your repository\n- add `/middleware.ts` to your .gitignore\n  - NOTE: include the `/` to not exclude any `middleware.ts` files in your `app` directory\n\n### next.config.js\n\n```js\nconst { withMiddleware } = require(\"@cxnpl/next-app-middleware\");\n\nconst nextConfig = {\n  // your next.js config\n};\n\nmodule.exports = withMiddleware(nextConfig);\n```\n\n## file conventions\n\nNOTE: unless stated otherwise can be in any segment of the app directory.\n\n### middleware.{ts,js}\n\nMiddlewares will be called first when a request reaches its segment. A `MiddlewareHandlerResult` can be returned to intercept the request and stop the handler chain early. If the middleware returns `void`, execution continues normally.\n\n```ts\nconst middleware: MiddlewareHandler = (req, res) => {\n  let visitor_id = req.cookies.get(\"visitor_id\")?.value;\n  if (!visitor_id) {\n    visitor_id = crypto.randomUUID();\n    res.cookies.set(\"visitor_id\", visitor_id);\n  }\n  req.waitUntil(trackVisit(visitor_id, req));\n};\n\nexport default middleware;\n```\n\n### forward.dynamic.{ts,js}\n\n(Can not exist in route group segment)\n\nDefine internal path forwards in this file. Export named functions that indicate what parameter will be rewritten. Used to forward [dyanmic] segments.\n\n```\n/app/\n  - [locale]\n    - page.tsx\n  - forward.dynamic.ts\n```\n\n```ts\n// app/forward.dynamic.ts\nexport const locale = () => {\n  return \"en\";\n};\n```\n\nIn this example the forward.dynamic.ts file declares a locale rewrite. This setup will result in the final middleware to consider any external request to `/` a request to `/[locale]` and will block all direct external requests to `/[locale]`\n\nNOTE: If you return void from any of the forward functions, request routing will continue in the current segment.\n\n```\n/app/\n  - [locale]\n    - page.tsx\n  - forward.dynamic.ts\n  - page.tsx\n```\n\n```ts\n// app/forward.dynamic.ts\nexport const locale = () => {\n  return;\n};\n```\n\nHere, the request will be routed to /app/page.tsx.\n\n### forward.static.{ts,js}\n\n(Can not exist in route group segment)\n\nDefine internal path forwards in this file. Export named functions that indicate what parameter will be rewritten. Used to forward static segments.\n\n```\n/app/\n  - hosted\n    - page.tsx\n  - forward.static.ts\n```\n\n```ts\n// app/forward.static.ts\nexport const hosted = () => {\n  return true;\n};\n```\n\nIn this example the forward.static.ts file declares a `hosted` rewrite. This setup will result in the final middleware to consider any external request to `/` a request to `/hosted` and will block all direct external requests to `/hosted`\n\nNOTE: If you return false from any of the forward functions, request routing will continue in the current segment. (See above for an example)\n\n### external.{ts,js}\n\nAn `external` file allows routing traffic to other applications, default export should be either of type `string` or `() => string | Promise<string>`:\n\n```ts\nconst origin = \"https://example.com\";\n\nexport default origin;\n```\n\n```ts\nconst getOrigin = async () => {\n  return \"http://localhost:3004\";\n};\n\nexport default getOrigin;\n```\n\nNOTE: Once an `external` file is found route collection is stopped, so any local pages in following segments will never be reached.\n\n### rewrite.{ts,js}\n\nA `rewrite` file indicates to the framework that the directory is an external path. The rewrite handler will receive the same arguments as a middleware handler would but can returns the final rewirite path if the request should be rewritten.\n\n### redirect.{ts,js}\n\nSimilar to `rewrite` but results in a redirect instead of a rewrite\n\n```ts\n/**\n * both rewrites and redirects can co-exist with pages and can\n * dynamically choose to not perform any action and continue matching.\n * Priority: rewrite > redirect > page\n */\n\n// /app/rewrite.ts\nconst rewrite: RewriteHandler = (req) => {\n  if (req.cookies.get(\"rewrite\")?.value === \"true\") return \"/rewritten\";\n};\n\n// /app/page.tsx\nexport default () => {\n  return <></>;\n};\n\nexport default rewrite;\n\n/**\n * since there is both a rewrite and a page in the same directory\n * any request that does not have the `rewrite` cookie set to `true`\n * will fall through to the page file while the ones that do have the\n * cookie set will be rewritten to `/rewritten`\n * Note: if `void` is returned and no futher handler exist a `MatchingError`\n * is thrown.\n */\n```\n\n### middleware.hooks.{ts,js}\n\nA collection of hooks that can be used to extend the middleware lifecylce. Unlike others, this file has to be in the root of your project instead of the app directory.\n\n#### notFound\n\nThis hook will be invoked if the middleware recieved a request that did not match any external page paths:\n\n```ts\nexport const notFound: NotFoundHook = () => {\n  // most hooks can return a NextResponse to override default behaviour\n  return NextResponse(null, { status: 404 });\n};\n```\n\n#### redirect\n\nThis hook will be invoked when a middleware returned a redirect response or a redirect file redirected the response:\n\n```ts\nexport const redirect: RedirectHook = (_req, _res, destination, status) => {\n  console.log(\n    `Redirecting to ${destination} with status ${status)`\n  );\n}\n```\n\n#### rewrite\n\nThis hook will be invoked when a middleware returned a rewrite response or a rewrite file redirected the response:\n\n```ts\nexport const rewrite: RewriteHook = (_req, _res, destination) => {\n  console.log(`Rewriting to ${destination}`);\n};\n```\n\n#### json\n\nThis hook will be invoked when a middleware resolved with a json response:\n\n```ts\nexport const json: JsonHook = (_req, _res, data) => {\n  return new NextResponse(yaml.stringfy(data), {\n    headers: {\n      \"content-type\": \"application/x-yaml\",\n    },\n  });\n};\n```\n\n#### params\n\nThis hook can be used to override the path params before the final path is created:\n\n```ts\nexport const params: ParamsHook = (params) => {\n  if (params.test) {\n    params.test = \"override\";\n  }\n  return params;\n};\n```\n\n#### response\n\nThis hook will receive the final response (`NextResponse`) and does allow for any final editing of the response before it is sent:\n\n```ts\nexport const response: ResponseHook = (finalResponse) => {\n  // collect metrics in here\n};\n```\n\nor\n\n```ts\nexport const response: ResponseHook = (finalResponse) => {\n  // Modify the response e.g. add a custom header\n  finalResponse.headers.set(\"x-custom-header\", \"value\");\n};\n```\n\n#### error\n\nInvoked when an error happens during matching or handler execution:\n\n```ts\nexport const error: ErrorHook = (req, res, err) => {\n  console.error(err);\n  // the error will be re-thrown if this hook does not return a response,\n  // causing a 500 response by default, if a response is returned, request\n  // processing continues\n  return new NextResponse(null, { status: 500 });\n};\n```\n\n## Publishing a new version to npm locally\n\nInstructions on how to push a new version of the package on your local machine.\n\nAt time of writing, you can ignore the failing release workflow (`.github/workflows/release.yml`) that is intended to publish on every push to `main` with a bumped root `package.json` version.\n\n\n### Prerequisites\n\n- An npm account that is listed as a collaborator on all three packages. Verify with:\n```bash\n  npm access list collaborators @cxnpl/next-app-middleware\n  npm access list collaborators @cxnpl/next-app-middleware-runtime\n  npm access list collaborators @cxnpl/next-app-middleware-codegen\n```\n- `pnpm` installed and matching the `packageManager` field in the root `package.json` (use `corepack enable` to get the pinned version).\n- The PR with your changes is merged to `main`, including the root `package.json` version bump.\n\n### Steps\n\n1. Sync `main` and install dependencies:\n\n   ```bash\n   git checkout main && git pull\n   pnpm install\n   ```\n\n2. Set the sub-package versions to match the root `package.json` version. The source files intentionally stay at `\"version\": \"0.0.0\"` between releases — the official tooling rewrites them at publish time, but for a manual publish you do it yourself. Edit the `version` field in each of:\n\n   - `packages/next-app-middleware/package.json`\n   - `packages/runtime/package.json`\n   - `packages/codegen/package.json`\n\n   Do **not** commit these edits — they exist only for the publish.\n\n3. Update every `workspace:0.0.0` cross-reference between the published packages to `workspace:<new version>`. `pnpm publish` rewrites `workspace:X.Y.Z` to the **literal** `X.Y.Z` — it does **not** read the workspace package's current version — so if you skip this step the published dependencies will point at `0.0.0` and consumers' `npm install` will fail with `ETARGET No matching version found`.\n\n   The references to update (leave the `tsconfig` ones alone — that package is private):\n\n   - `packages/codegen/package.json` → `\"@cxnpl/next-app-middleware-runtime\": \"workspace:<new version>\"`\n   - `packages/next-app-middleware/package.json` → `\"@cxnpl/next-app-middleware-codegen\": \"workspace:<new version>\"`\n   - `packages/next-app-middleware/package.json` → `\"@cxnpl/next-app-middleware-runtime\": \"workspace:<new version>\"`\n   - `examples/basic/package.json` → `\"@cxnpl/next-app-middleware\": \"workspace:<new version>\"`\n   - `examples/basic-js/package.json` → `\"@cxnpl/next-app-middleware\": \"workspace:<new version>\"`\n\n   These edits are also local-only — revert in step 8.\n\n4. Build all packages, bypassing the turbo cache:\n\n   ```bash\n   pnpm build --force\n   ```\n\n5. Authenticate with npm using the collaborator account:\n\n   ```bash\n   npm login\n   npm whoami   # sanity check: prints the collaborator username\n   ```\n\n6. Publish all three packages in topological order. `pnpm -r publish` walks the workspace graph and substitutes the `workspace:` references with the real versions:\n\n   ```bash\n   pnpm -r publish --access public --no-git-checks\n   ```\n\n7. Verify each package is live at the new version, and that the dependencies of `@cxnpl/next-app-middleware` resolve correctly:\n\n   ```bash\n   npm view @cxnpl/next-app-middleware version\n   npm view @cxnpl/next-app-middleware-runtime version\n   npm view @cxnpl/next-app-middleware-codegen version\n   npm view @cxnpl/next-app-middleware dependencies   # should NOT be 0.0.0\n   ```\n\n8. Discard the local version bumps so source stays at `0.0.0`:\n\n   ```bash\n   git checkout -- packages/*/package.json examples/*/package.json\n   ```\n","readmeFilename":"README.md"}