# 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)