Skip to content

Commit

Permalink
Fix the Script component to not throw within inline scripts (#2428)
Browse files Browse the repository at this point in the history
* Fix the `Script` component to not throw within inline scripts

* Apply suggestions from code review

---------

Co-authored-by: Fran Dios <frankdiox@gmail.com>
  • Loading branch information
blittle and frandiox authored Aug 14, 2024
1 parent 844417e commit b0d3bc0
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/flat-foxes-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/hydrogen': patch
---

Fix the `Script` component to not throw when using it for inline scripts with `dangerouslySetInnerHTML`
37 changes: 37 additions & 0 deletions packages/hydrogen/src/csp/Script.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,27 @@ describe('<Script />', () => {
`);
});

it('loads an inline script', () => {
const {asFragment} = render(
createElement(NonceProvider, {
value: 'somenonce',
children: createElement(Script, {
dangerouslySetInnerHTML: {__html: 'alert("hi")'},
}),
}),
);

expect(asFragment()).toMatchInlineSnapshot(`
<DocumentFragment>
<script
nonce="somenonce"
>
alert("hi")
</script>
</DocumentFragment>
`);
});

it('should load scripts after hydration', () => {
const {asFragment} = render(
createElement(NonceProvider, {
Expand All @@ -53,4 +74,20 @@ describe('<Script />', () => {
attributes: {},
});
});

it('throws without a src prop when using waitForHydration', () => {
function renderComponent() {
render(
createElement(NonceProvider, {
value: 'somenonce',
children: createElement(Script, {
waitForHydration: true,
}),
}),
);
}
expect(renderComponent).toThrowError(
'`waitForHydration` with the Script component requires a `src` prop',
);
});
});
8 changes: 6 additions & 2 deletions packages/hydrogen/src/csp/Script.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export const Script = forwardRef<HTMLScriptElement, ScriptProps>(
(props, ref) => {
const {waitForHydration, src, ...rest} = props;

if (!src) throw new Error('Script components require a `src` prop');
if (waitForHydration) return <LazyScript src={src} options={rest} />;

const nonce = useNonce();
Expand All @@ -36,9 +35,14 @@ function LazyScript({
src,
options,
}: {
src: string;
src?: string;
options: JSX.IntrinsicElements['script'];
}) {
if (!src)
throw new Error(
'`waitForHydration` with the Script component requires a `src` prop',
);

useLoadScript(src, {
attributes: options as Record<string, string>,
});
Expand Down

0 comments on commit b0d3bc0

Please sign in to comment.