How to Use Content Security Policy in Shopify Hydrogen for Domain-Specific Media Access
Control which domains can serve fonts, images, and styles in your Hydrogen app using createContentSecurityPolicy.
Import createContentSecurityPolicy:Hydrogen provides a utility to easily configure CSP headers.
import {createContentSecurityPolicy} from '@shopify/hydrogen';
entry.server.tsx
Configure Allowed Sources:Pass CSP directives into createContentSecurityPolicy. You can specify domains for specific media types:
const {nonce, header, NonceProvider} = createContentSecurityPolicy({
fontSrc: [
`'self'`,
'fonts.googleapis.com',
'fonts.gstatic.com'
],
imgSrc: [
`'self'`,
'data:',
'https://cdn.shopify.com',
'https://d22po4pjz3o32e.cloudfront.net'
],
styleSrc: [
`'self'`,
'fonts.googleapis.com',
'fonts.gstatic.com',
`'unsafe-inline'` // Required for inline styles
],
shop: {
checkoutDomain: context.env.PUBLIC_CHECKOUT_DOMAIN,
storeDomain: context.env.PUBLIC_STORE_DOMAIN,
},
});
entry.server.tsx
Apply the CSP Header to the Response:Inject the CSP header into the outgoing response.
responseHeaders.set('Content-Security-Policy', header);
entry.server.tsx
Wrap the Rendered App with NonceProvider:Ensures nonce support for inline scripts/styles if needed.
const body = await renderToReadableStream(
<NonceProvider>
<RemixServer context={remixContext} url={request.url} nonce={nonce} />
</NonceProvider>,
{ nonce, signal: request.signal }
);
entry.server.tsx
Final Response Setup:
return new Response(body, {
headers: responseHeaders,
status: responseStatusCode,
});
entry.server.tsx