import { headers } from 'next/headers';
import type { CSPNonce } from './csp';
/**
* Retrieves the CSP nonce from request headers in server components
*
* The nonce is generated by middleware.ts and stored in the 'x-nonce' header
* for server components to access. This nonce should be added to inline scripts
* and styles to satisfy Content Security Policy requirements.
*
* @returns The CSP nonce value if available, undefined otherwise
*
* @example
* ```tsx
* import { getNonce } from '@/lib/security/get-nonce';
*
* export default function Layout() {
* const nonce = getNonce();
*
* return (
* <html>
* <head>
* <script nonce={nonce}>
* // Inline script that needs CSP approval
* </script>
* </head>
* </html>
* );
* }
* ```
*/
export function getNonce(): CSPNonce | undefined {
try {
// Access the headers in server component context
const headersList = headers();
// Retrieve the nonce that was set by middleware
const nonce = headersList.get('x-nonce');
// Return the nonce if it exists, undefined otherwise
return nonce ?? undefined;
} catch (error) {
// Headers can only be accessed in server component context
// If this fails (e.g., being called in a client component or static export),
// gracefully return undefined rather than throwing
if (process.env.NODE_ENV === 'development') {
console.warn(
'getNonce: Unable to access headers. This function must be called in a server component context.',
error
);
}
return undefined;
}
}