How to Configure CORS for 9Router API Routes: A Complete Guide
TLDR: 9Router implements CORS by defining a CORS_HEADERS constant with standard access-control headers, exporting an OPTIONS handler for preflight requests, and spreading those headers into every response in Next.js Edge Runtime API routes.
9Router (decolua/9router) is a Next.js-based routing layer for AI model APIs that runs on the Edge Runtime. To configure CORS for 9Router API routes, you must explicitly set response headers in each route handler, as the Edge Runtime does not use traditional middleware. This guide shows you the exact pattern used in the source code to handle cross-origin requests securely.
The Standard CORS Pattern in 9Router
According to the 9Router source code, every API route follows a consistent three-step pattern to handle cross-origin requests. This approach is necessary because Edge Runtime routes are stateless and require explicit header management.
The implementation in src/app/api/v1/messages/count_tokens/route.js demonstrates the canonical approach:
-
Define the header map – Create a
CORS_HEADERSobject containing the three required CORS response headers. -
Handle preflight requests – Export an
OPTIONSfunction that returns aResponsewith the CORS headers and no body. -
Merge into responses – Spread the
CORS_HEADERSobject into the headers of everyPOST,GET, or other method response.
Default Permissive Configuration
By default, 9Router routes use a permissive CORS policy suitable for development. The src/app/api/v1/chat/completions/route.js file implements the following standard headers:
const CORS_HEADERS = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "POST, OPTIONS",
"Access-Control-Allow-Headers": "*"
};
export async function OPTIONS() {
return new Response(null, { headers: CORS_HEADERS });
}
export async function POST(request) {
// ... processing logic ...
return new Response(JSON.stringify({ result: "ok" }), {
status: 200,
headers: { "Content-Type": "application/json", ...CORS_HEADERS }
});
}
This configuration allows requests from any origin (*), accepts POST and OPTIONS methods, and permits any request headers. The same pattern appears in src/app/api/tags/route.js for GET endpoints.
Customizing CORS for Production
For production deployments, you should restrict CORS to specific domains and methods. You can customize the headers directly in each route file or extract them into a shared utility.
Restricting Allowed Origins
To limit access to a specific dashboard or domain, modify the Access-Control-Allow-Origin value in your route file:
const CORS_HEADERS = {
"Access-Control-Allow-Origin": "https://my-dashboard.example.com",
"Access-Control-Allow-Methods": "POST, GET, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization"
};
Creating a Shared CORS Utility
Instead of copying headers into every route, create a shared module at src/app/api/_common/cors.js:
// src/app/api/_common/cors.js
export const CORS_HEADERS = {
"Access-Control-Allow-Origin": "https://app.mycompany.com",
"Access-Control-Allow-Methods": "POST, GET, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization"
};
Then import this utility in your route handlers:
import { CORS_HEADERS } from "../../_common/cors";
export async function OPTIONS() {
return new Response(null, { headers: CORS_HEADERS });
}
export async function POST(request) {
// ... process request ...
return new Response(JSON.stringify({ success: true }), {
status: 200,
headers: { "Content-Type": "application/json", ...CORS_HEADERS }
});
}
Cloudflare Worker CORS Implementation
For the Cloudflare Worker deployment (located in the cloud/ directory), the same pattern applies. Files like cloud/src/handlers/sync.js and cloud/src/handlers/countTokens.js implement identical CORS header management, ensuring consistent behavior between the Next.js Edge Runtime and serverless edge environments.
Summary
- 9Router uses explicit header management in Next.js Edge Runtime routes rather than middleware.
- Every route must export an
OPTIONShandler that returns CORS headers to handle preflight requests. - The
CORS_HEADERSconstant in files likesrc/app/api/v1/messages/count_tokens/route.jsdefines the access-control policy. - Spread the headers into every response using
...CORS_HEADERSto ensure cross-origin compatibility. - Extract shared configurations into
src/app/api/_common/cors.jsfor maintainability across multiple endpoints.
Frequently Asked Questions
How do I enable CORS for all origins in 9Router?
Set the Access-Control-Allow-Origin header to * in your CORS_HEADERS object. This is the default configuration found in src/app/api/tags/route.js and other built-in endpoints, allowing any domain to access your API.
Where are the CORS headers defined in 9Router?
CORS headers are defined locally in each API route file, such as src/app/api/v1/chat/completions/route.js and src/app/api/v1/messages/count_tokens/route.js. Each file contains a CORS_HEADERS constant that you can modify or replace with a shared import.
How do I handle preflight OPTIONS requests in 9Router?
Export an OPTIONS function from your route file that returns a Response with status 200 and the CORS_HEADERS object. This tells browsers which cross-origin requests are permitted before sending the actual POST or GET request.
Can I use Next.js middleware for CORS in 9Router?
No. Because 9Router runs on the Edge Runtime with explicit route handlers, CORS must be implemented directly in each route's OPTIONS and response handlers. The codebase demonstrates this pattern consistently across all endpoints including cloud/src/handlers/sync.js.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →