# createContentSecurityPolicy Create a [content security policy](https://shopify.dev/docs/custom-storefronts/hydrogen/content-security-policy) to secure your application. The default content security policy includes exclusions for cdn.shopify.com and a script nonce. ```jsx import {RemixServer} from '@remix-run/react'; import isbot from 'isbot'; import {renderToReadableStream} from 'react-dom/server'; import {createContentSecurityPolicy} from '@shopify/hydrogen'; export default async function handleRequest( request, responseStatusCode, responseHeaders, remixContext, ) { const {nonce, header, NonceProvider} = createContentSecurityPolicy({ // pass a custom directive to load content from a third party domain styleSrc: [ "'self'", 'https://cdn.shopify.com', 'https://some-custom-css.cdn', ], }); const body = await renderToReadableStream( , { nonce, signal: request.signal, onError(error) { // eslint-disable-next-line no-console console.error(error); responseStatusCode = 500; }, }, ); if (isbot(request.headers.get('user-agent'))) { await body.allReady; } responseHeaders.set('Content-Type', 'text/html'); responseHeaders.set('Content-Security-Policy', header); return new Response(body, { headers: responseHeaders, status: responseStatusCode, }); } ``` ```tsx import type {EntryContext} from '@shopify/remix-oxygen'; import {RemixServer} from '@remix-run/react'; import isbot from 'isbot'; import {renderToReadableStream} from 'react-dom/server'; import {createContentSecurityPolicy} from '@shopify/hydrogen'; export default async function handleRequest( request: Request, responseStatusCode: number, responseHeaders: Headers, remixContext: EntryContext, ) { const {nonce, header, NonceProvider} = createContentSecurityPolicy({ // pass a custom directive to load content from a third party domain styleSrc: [ "'self'", 'https://cdn.shopify.com', 'https://some-custom-css.cdn', ], }); const body = await renderToReadableStream( , { nonce, signal: request.signal, onError(error) { // eslint-disable-next-line no-console console.error(error); responseStatusCode = 500; }, }, ); if (isbot(request.headers.get('user-agent'))) { await body.allReady; } responseHeaders.set('Content-Type', 'text/html'); responseHeaders.set('Content-Security-Policy', header); return new Response(body, { headers: responseHeaders, status: responseStatusCode, }); } ``` ## Props ### CreateContentSecurityPolicyGeneratedType #### Returns: ContentSecurityPolicy #### Params: - directives: Record export function createContentSecurityPolicy( directives: Record = {}, ): ContentSecurityPolicy { const nonce = generateNonce(); const header = createCSPHeader(nonce, directives); const Provider = ({children}: {children: ReactNode}) => { return createElement(NonceProvider, {value: nonce}, children); }; return { nonce, header, NonceProvider: Provider, }; } ### ContentSecurityPolicy ### nonce value: `string` A randomly generated nonce string that should be passed to any custom `script` element ### header value: `string` The content security policy header ### NonceProvider value: `ComponentType<{children: ReactNode}>` ## Related - [useNonce](https://shopify.dev/docs/api/hydrogen/2023-07/hooks/usenonce) - [Script](https://shopify.dev/docs/api/hydrogen/2023-07/components/script)