CORS, or Cross-Origin Resource Sharing, is a mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources. Without CORS, modern browsers would block cross-origin requests for security reasons, preventing malicious behavior.
Why is CORS Necessary?
When building modern web applications, the frontend and backend often run on different domains or ports, especially during development. For example:
- Frontend:
http://localhost:3000
- Backend:
http://localhost:5000
By default, browsers block requests from the frontend to the backend due to the Same-Origin Policy. This is where CORS comes inโit acts as a controlled way to bypass the same-origin restriction, enabling secure communication.
A typical CORS scenario involves the frontend making an API call to the backend, and the backend explicitly allowing such requests by including certain headers in its response.
Configuring CORS in NestJS with Fastify
While enabling CORS in a NestJS application using Express is straightforward, using Fastify requires a slightly different approach. When I was working on a project, I decided to switch from Viteโs proxy server to enabling CORS on my Fastify server, both as a learning opportunity and for better alignment with production setups. However, I found the documentation and available articles on enabling CORS for Fastify in NestJS to be sparse.
Hereโs how I tackled it.
Step 1: Define CORS Options
To keep things clean and reusable, I created a dedicated cors.options.ts
file for my CORS
configuration. Here's what it looks like:
Step 2: Use CORS Options in the Main Application
In the main.ts
file, I configured the Fastify server to use these options:
Key Points to Note
- Origins: I specified the allowed origins explicitly, such as
http://localhost:3000
for development. Add production or staging URLs as needed. - Methods: Only specific HTTP methods like
GET
,POST
, andDELETE
are allowed. - Credentials: By setting
credentials: true
, the server allows cookies or authentication tokens to be sent with requests. - Modular Approach: Placing the CORS options in a separate file helps maintain modularity and makes it easier to modify configurations in the future.
Axios Configuration for the Frontend
Here is my axiosConfig.ts
file, showing how I have configured Axios for the frontend:
Learnings and Final Thoughts
While configuring CORS for Fastify in NestJS, I initially used Express-specific solutions, which felt incorrect and hacky. After thorough research, I found the proper way to enable it using the enableCors method of the Fastify adapter.
If youโre using my Verdant turborepo template, you can find an example of this CORS configuration there. The repo also demonstrates how to structure a modern monorepo using tools like TurboRepo and Vite.
If you want to learn more about CORS, check out this MDN article, which does a fantastic job of explaining the concept in detail.
CORS can seem tricky initially, but with the right approach, itโs straightforward to configure and ensures secure communication between your frontend and backend.