Configuring Security Headers in Next.js
Security headers are rules your server sends the browser to prevent attacks like XSS and clickjacking. In Next.js, you configure these globally in `next.config.js`.
WHY IT EXISTS: Browsers have powerful features, but some can be exploited by malicious actors. Without instructions from your server, a browser might execute a malicious script injected into your page (XSS) or render your site in a frame on an attacker's site (clickjacking). Security headers were created to give your server control over the browser's security policies for your content.
THE MENTAL MODEL: Think of security headers as a bouncer for your website, but one who gives instructions to the browser, not the user. Your Next.js app tells the browser, "Only load scripts from our own domain," or "Don't allow anyone to put this page in an iframe." The browser then enforces these rules, blocking many common attack vectors before they can even run.
HOW IT WORKS: In Next.js, you configure headers in the next.config.js file. You export an async function named headers that returns an array of objects. Each object specifies a source path pattern (e.g., '/:path*') and a headers array. Each header in that array is an object with a key (the header name, like 'Content-Security-Policy') and a value (the policy string). Next.js applies these headers to the HTTP response for any matching request path.
WHEN TO USE IT: You should configure security headers for every production Next.js application. They are a fundamental, low-effort, high-impact security measure. Key headers to implement include Content-Security-Policy (CSP) to control resource loading, X-Content-Type-Options to prevent MIME-sniffing, and X-Frame-Options to prevent clickjacking.
WHEN NOT TO USE IT: There is rarely a reason to not use security headers. However, you might temporarily disable or relax a very strict Content Security Policy during local development to allow for tools like browser extensions or hot-reloading scripts to function correctly. Be careful not to ship these relaxed development configurations to production.
ONE CANONICAL EXAMPLE: To implement a basic set of security headers in next.config.js, you would add an async headers function. For example:
module.exports = { async headers() { return [ { source: '/:path*', headers: [ { key: 'X-Frame-Options', value: 'SAMEORIGIN' }, { key: 'X-Content-Type-Options', value: 'nosniff' }, { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' } ], }, ] }, }
This example applies several common security headers to all routes in the application. A robust Content-Security-Policy is more complex and application-specific.
Read the original → nextjs.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.