What is the location of your example repository?
No response
Which package or tool is having this issue?
Hydrogen
What version of that package or tool are you using?
0.0.0-preview-8a708a8-20260708155454
What version of React Router 7 are you using?
7.15.1
Steps to Reproduce
Environment:
- React 19.2.x
- React Router 7.15.1
- A request-scoped CSP nonce provided during SSR
- Render
ShopifyScripts with the nonce:
const nonce = useNonce();
<ShopifyScripts
nonce={nonce}
i18n={{country: 'US', language: 'EN'}}
routes={routes}
/>
- On the client, read the server nonce from an existing script's
.nonce property and provide it through the same nonce context before hydration.
- Perform a full document reload with the browser console open.
Browsers hide a parsed script's nonce content attribute: the DOM exposes nonce="" while the .nonce property retains the real value. Two client-only workarounds are incomplete:
- Hydrating with
undefined still differs from the browser-exposed nonce="".
- Hydrating with
"" makes getShopifyScriptTags() omit nonce attributes because it uses const nonceAttributes = nonce ? {nonce} : undefined.
Expected Behavior
ShopifyScripts should hydrate without reporting an attribute mismatch caused solely by the browser's standard nonce-hiding behavior.
Unrelated hydration diagnostics should remain visible.
Actual Behavior
React reports that attributes of the server-rendered HTML do not match the client properties. The element diff points to the external Shopify standard-actions script generated by ShopifyScripts; its nonce is exposed as nonce="" in the parsed DOM even though the client has the real nonce.
The inline generated scripts do not warn because the React binding already adds suppressHydrationWarning whenever innerHTML is present. The external generated script is the uncovered case.
This produces a hydration warning on every full page load for storefronts using both CSP nonces and the framework-agnostic ShopifyScripts binding, and it obscures unrelated actionable hydration diagnostics.
A minimal fix is to suppress this known comparison when the caller supplied the nonce option, including an empty hydration-frame value:
return createElement(tagName, {
key: index,
+ ...(scriptOptions.nonce !== undefined
+ ? {suppressHydrationWarning: true}
+ : {}),
...getReactAttributes(attributes),
A narrower variant could apply the condition only to generated script tags. This keeps unrelated hydration warnings visible when no nonce option is present. The same change is needed in development and production bindings.
What is the location of your example repository?
No response
Which package or tool is having this issue?
Hydrogen
What version of that package or tool are you using?
0.0.0-preview-8a708a8-20260708155454
What version of React Router 7 are you using?
7.15.1
Steps to Reproduce
Environment:
ShopifyScriptswith the nonce:.nonceproperty and provide it through the same nonce context before hydration.Browsers hide a parsed script's nonce content attribute: the DOM exposes
nonce=""while the.nonceproperty retains the real value. Two client-only workarounds are incomplete:undefinedstill differs from the browser-exposednonce="".""makesgetShopifyScriptTags()omit nonce attributes because it usesconst nonceAttributes = nonce ? {nonce} : undefined.Expected Behavior
ShopifyScriptsshould hydrate without reporting an attribute mismatch caused solely by the browser's standard nonce-hiding behavior.Unrelated hydration diagnostics should remain visible.
Actual Behavior
React reports that attributes of the server-rendered HTML do not match the client properties. The element diff points to the external Shopify standard-actions script generated by
ShopifyScripts; its nonce is exposed asnonce=""in the parsed DOM even though the client has the real nonce.The inline generated scripts do not warn because the React binding already adds
suppressHydrationWarningwheneverinnerHTMLis present. The external generated script is the uncovered case.This produces a hydration warning on every full page load for storefronts using both CSP nonces and the framework-agnostic
ShopifyScriptsbinding, and it obscures unrelated actionable hydration diagnostics.A minimal fix is to suppress this known comparison when the caller supplied the nonce option, including an empty hydration-frame value:
return createElement(tagName, { key: index, + ...(scriptOptions.nonce !== undefined + ? {suppressHydrationWarning: true} + : {}), ...getReactAttributes(attributes),A narrower variant could apply the condition only to generated
scripttags. This keeps unrelated hydration warnings visible when no nonce option is present. The same change is needed in development and production bindings.