In entry.server.tsx (or the root loader Response headers) use the createContentSecurityPolicy helper from @shopify/hydrogen to generate CSP headers appropriate for a Hydrogen storefront
Pass a config object to createContentSecurityPolicy specifying additional script-src, style-src, img-src, and connect-src origins beyond the defaults; common additions are your analytics vendor domains and Google Fonts
Shopify Checkout runs on checkout.shopify.com — if you redirect to hosted checkout you do not need to include checkout scripts in your CSP; only include them if you embed checkout UI extensions in your Hydrogen app
Add the generated nonce from createContentSecurityPolicy to any inline scripts or link elements in your <head> using the nonce prop; Remix's <Scripts /> and <LiveReload /> components accept a nonce prop
Set the Content-Security-Policy header on the response in the handleRequest function; use Content-Security-Policy-Report-Only first to identify violations without blocking, then switch to enforcing mode
Review browser console CSP violation reports after switching to enforcing mode and iteratively add missing origins to the policy config until all legitimate resources load
Known gotchas
The nonce changes on every request — do not cache HTML responses that contain the nonce, as cached pages will have an expired nonce that the browser will reject when validating inline scripts
Shopify's CDN domains can vary by region and over time; use createContentSecurityPolicy rather than hand-writing the header to ensure all required Shopify domains are included
If you use a third-party pixel or analytics script loaded dynamically, it will be blocked by CSP unless you add its domain explicitly; audit all dynamically injected scripts before enforcing CSP
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp