Skip to main content
Version: 0.23
note

Last checked with Wasp 0.21.

This guide depends on external libraries or services, so it may become outdated over time. We do our best to keep it up to date, but make sure to check their documentation for any changes.

Multiple Domains CORS

This guide shows you how to configure CORS (Cross-Origin Resource Sharing) to support multiple domains in your Wasp application using custom global middleware.

Prerequisitesโ€‹

Make sure you have a Wasp project set up. If you haven't, follow the Getting Started guide first.

When You Need Thisโ€‹

By default, Wasp configures CORS to allow requests only from your client URL (defined by WASP_WEB_CLIENT_URL). You might need to support multiple domains when:

  • You have multiple domains for the same client application
  • You're building a public API
  • You're migrating from one domain to another

Setting up Multiple Domain CORSโ€‹

1. Configure global middleware in main.waspโ€‹

Add the server middleware configuration:

main.wasp
app CorsTest {
wasp: {
version: "^0.21.0"
},
title: "cors-test",
server: {
middlewareConfigFn: import { getGlobalMiddleware } from "@src/middleware",
}
}

route RootRoute { path: "/", to: MainPage }
page MainPage {
component: import { MainPage } from "@src/MainPage"
}

query getSomeData {
fn: import { getSomeData } from "@src/data",
entities: []
}

2. Create the middleware configurationโ€‹

Create a middleware file that configures CORS with multiple origins:

src/middleware.ts
import cors from "cors";
import { config, type MiddlewareConfigFn } from "wasp/server";

export const getGlobalMiddleware: MiddlewareConfigFn = (middlewareConfig) => {
// Add extra domains to the existing allowed CORS origins.
const origin = [
...config.allowedCORSOrigins,
"https://app.example.com",
"https://admin.example.com",
];

middlewareConfig.set("cors", cors({ origin }));

return middlewareConfig;
};

3. Example query handlerโ€‹

Here's an example of a query that will now be accessible from multiple domains:

src/data.ts
import { GetSomeData } from "wasp/server/operations";

export const getSomeData: GetSomeData = async (_args, _context) => {
return {
someData: "Hello from the server!",
};
};

Configuration Optionsโ€‹

Using Environment Variablesโ€‹

You can make the allowed domains configurable via environment variables:

src/middleware.ts
import cors from "cors";
import { config, type MiddlewareConfigFn } from "wasp/server";

export const getGlobalMiddleware: MiddlewareConfigFn = (middlewareConfig) => {
// Parse additional domains from environment variable.
const additionalDomains = process.env.CORS_ALLOWED_DOMAINS?.split(",") ?? [];

const origin = [...config.allowedCORSOrigins, ...additionalDomains];

middlewareConfig.set("cors", cors({ origin }));

return middlewareConfig;
};

Then in your .env.server:

.env.server
CORS_ALLOWED_DOMAINS=https://app.example.com,https://admin.example.com

Dynamic Origin Validationโ€‹

For more complex scenarios, you can use a function to validate origins:

src/middleware.ts
import cors from "cors";
import { MiddlewareConfigFn } from "wasp/server";

export const getGlobalMiddleware: MiddlewareConfigFn = (config) => {
config.set(
"cors",
cors({
origin: (origin, callback) => {
const allowedPatterns = [
/^https:\/\/.*\.example\.com$/, // Any subdomain of example.com
/^http:\/\/localhost:\d+$/, // Any localhost port
];

if (
!origin ||
allowedPatterns.some((pattern) => pattern.test(origin))
) {
callback(null, true);
} else {
callback(new Error("Not allowed by CORS"));
}
},
}),
);

return config;
};

Full CORS Configurationโ€‹

For complete control over CORS, you can set all options:

src/middleware.ts
import cors from "cors";
import { MiddlewareConfigFn } from "wasp/server";

export const getGlobalMiddleware: MiddlewareConfigFn = (config) => {
config.set(
"cors",
cors({
origin: ["https://app.example.com", "https://admin.example.com"],
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
allowedHeaders: ["Content-Type", "Authorization"],
credentials: true,
maxAge: 86400, // 24 hours
}),
);

return config;
};

Security Considerationsโ€‹

  • Never use origin: "*" or origin: [/.*/] in production โ€” always restrict origins to specific domains
  • Always explicitly list the domains you want to allow
  • Consider using environment variables to manage allowed domains across environments
  • Regularly audit your allowed domains list