diff --git a/lib/live_svelte.ex b/lib/live_svelte.ex
index c54d117..cd84895 100644
--- a/lib/live_svelte.ex
+++ b/lib/live_svelte.ex
@@ -45,6 +45,18 @@ defmodule LiveSvelte do
doc: "Class to apply to the Svelte component",
examples: ["my-class", "my-class another-class"]
+ attr :csp_nonce, :string,
+ default: nil,
+ doc: "A Content-Security-Policy nonce for the generated
{raw(@ssr_render["head"])}
-
{raw(@ssr_render["html"])}
diff --git a/package.json b/package.json
index 5207fab..f272340 100644
--- a/package.json
+++ b/package.json
@@ -16,8 +16,8 @@
},
"exports": {
".": {
- "import": "./assets/js/live_svelte/index.ts",
- "types": "./assets/js/live_svelte/types.d.ts"
+ "types": "./assets/js/live_svelte/types.d.ts",
+ "import": "./assets/js/live_svelte/index.ts"
},
"./vitePlugin": "./assets/js/live_svelte/vite_plugin.js"
},
diff --git a/test/csp_nonce_test.exs b/test/csp_nonce_test.exs
new file mode 100644
index 0000000..6360564
--- /dev/null
+++ b/test/csp_nonce_test.exs
@@ -0,0 +1,60 @@
+defmodule LiveSvelte.CspNonceTest do
+ use ExUnit.Case, async: true
+
+ defp render_html(opts) do
+ %{
+ __changed__: nil,
+ socket: nil,
+ name: "TestComponent",
+ id: "test-csp",
+ key: nil,
+ props: %{},
+ ssr: false,
+ class: nil,
+ loading: [],
+ inner_block: [],
+ csp_nonce: opts[:csp_nonce],
+ csp_script_nonce: opts[:csp_script_nonce],
+ csp_style_nonce: opts[:csp_style_nonce]
+ }
+ |> LiveSvelte.svelte()
+ |> Phoenix.HTML.Safe.to_iodata()
+ |> IO.iodata_to_binary()
+ end
+
+ setup do
+ %{nonce: System.unique_integer([:positive])}
+ end
+
+ test "no nonce attributes when none specified" do
+ refute render_html(%{}) =~ "nonce="
+ end
+
+ test "csp_nonce applies to both script and style", %{nonce: nonce} do
+ html = render_html(%{csp_nonce: nonce})
+
+ assert html =~ ~r/