diff --git a/.changeset/fix-svelte-csp-violations.md b/.changeset/fix-svelte-csp-violations.md
new file mode 100644
index 00000000..3670e1d1
--- /dev/null
+++ b/.changeset/fix-svelte-csp-violations.md
@@ -0,0 +1,5 @@
+---
+"@unpic/svelte": patch
+---
+
+Fix CSP violations by filtering undefined event handlers in Svelte 5. When event handler properties like `onload` and `onerror` are present but undefined in spread props, Svelte 5 adds internal event bindings that trigger CSP violations. The fix filters out only undefined event handlers while preserving explicitly passed handlers.
diff --git a/packages/svelte/src/lib/base/image.svelte b/packages/svelte/src/lib/base/image.svelte
index 55aa5087..fff6fe36 100644
--- a/packages/svelte/src/lib/base/image.svelte
+++ b/packages/svelte/src/lib/base/image.svelte
@@ -24,10 +24,24 @@
.filter(Boolean)
.join(";"),
);
+
+ // Filter out undefined event handlers to prevent CSP violations in Svelte 5
+ // When event handler properties are present but undefined in the spread object,
+ // Svelte 5 adds internal event bindings that violate CSP policies
+ const filteredProps = $derived(
+ Object.fromEntries(
+ Object.entries(props).filter(([key, value]) => {
+ // Keep non-event-handler properties
+ if (!key.startsWith("on")) return true;
+ // Keep event handlers that are explicitly defined by the user
+ return value !== undefined;
+ })
+ )
+ );
{
+ // Keep non-event-handler properties
+ if (!key.startsWith("on")) return true;
+ // Keep event handlers that are explicitly defined by the user
+ return value !== undefined;
+ })
+ )
+ );
-
+
diff --git a/packages/svelte/src/lib/image.svelte b/packages/svelte/src/lib/image.svelte
index 91447fa5..a41312ea 100644
--- a/packages/svelte/src/lib/image.svelte
+++ b/packages/svelte/src/lib/image.svelte
@@ -43,10 +43,24 @@
aspectRatio: _aspectRatio,
...rest
} = props;
+
+ // Filter out undefined event handlers to prevent CSP violations in Svelte 5
+ // When event handler properties are present but undefined in the spread object,
+ // Svelte 5 adds internal event bindings that violate CSP policies
+ const filteredRest = $derived(
+ Object.fromEntries(
+ Object.entries(rest).filter(([key, value]) => {
+ // Keep non-event-handler properties
+ if (!key.startsWith("on")) return true;
+ // Keep event handlers that are explicitly defined by the user
+ return value !== undefined;
+ })
+ )
+ );
{
+ // Keep non-event-handler properties
+ if (!key.startsWith("on")) return true;
+ // Keep event handlers that are explicitly defined by the user
+ return value !== undefined;
+ })
+ )
+ );
-
+
diff --git a/packages/svelte/test/svelte.test.ts b/packages/svelte/test/svelte.test.ts
index 03101979..24eed4c0 100644
--- a/packages/svelte/test/svelte.test.ts
+++ b/packages/svelte/test/svelte.test.ts
@@ -27,4 +27,45 @@ describe("the Svelte component", () => {
expectSourcePropsToMatchTransformed(source, props);
});
}
+
+ test("filters out undefined event handlers to prevent CSP violations", () => {
+ const props = {
+ src: "https://cdn.shopify.com/static/sample-images/bath_grande_crop_center.jpeg",
+ layout: "constrained" as const,
+ width: 800,
+ height: 600,
+ alt: "Test image",
+ // Simulating the case where TypeScript types include these but they're undefined
+ onload: undefined,
+ onerror: undefined,
+ };
+ render(Image, { props });
+ const img = screen.getByAltText("Test image");
+ expect(img).toBeTruthy();
+ // Verify undefined event handlers are not present as attributes
+ expect(img.getAttribute("onload")).toBeNull();
+ expect(img.getAttribute("onerror")).toBeNull();
+ });
+
+ test("preserves explicitly defined event handlers", () => {
+ const onloadHandler = () => console.log("loaded");
+ const onerrorHandler = () => console.log("error");
+ const props = {
+ src: "https://cdn.shopify.com/static/sample-images/bath_grande_crop_center.jpeg",
+ layout: "constrained" as const,
+ width: 800,
+ height: 600,
+ alt: "Test image with handlers",
+ onload: onloadHandler,
+ onerror: onerrorHandler,
+ };
+ render(Image, { props });
+ const img = screen.getByAltText(
+ "Test image with handlers",
+ );
+ expect(img).toBeTruthy();
+ // Verify explicit event handlers are present
+ // In Svelte 5, these will be bound using Svelte's event system
+ // We can't directly check the handler functions, but we verify the component renders without error
+ });
});