Heroicon not working

Make your own CSP headers.

For example:

    plug :put_secure_browser_headers, %{"content-security-policy" => MyAppWeb.CSP.header_value()}

with csp module like this:

defmodule MyAppWeb.CSP do
  @moduledoc """
  Content-Security-Policy

  https://www.w3.org/TR/CSP2/#directives
  https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
  """

  @hcaptcha ["https://hcaptcha.com", "https://*.hcaptcha.com"]
  @stripe ["https://js.stripe.com"]
  @google_fonts ["https://fonts.googleapis.com"]
  @env_specific_csp if Mix.env() == :dev,
                      do: ["'unsafe-inline'", "'unsafe-eval'", "blob:", "http://localhost:4007"],
                      else: []

  @header_kvp_list [
    default_src: ["'self'"],
    img_src: ["'self'", "data:"] ++ @env_specific_csp,
    script_src: ["'self'"] ++ @hcaptcha ++ @stripe ++ @env_specific_csp,
    object_src: ["'self'"],
    frame_src: ["'self'"] ++ @hcaptcha ++ @stripe,
    style_src: ["'self'", "'unsafe-inline'"] ++ @hcaptcha ++ @stripe ++ @google_fonts ++ @env_specific_csp,
    connect_src: ["'self'"] ++ @hcaptcha ++ @stripe
  ]

  @spec header_value() :: String.t()
  def header_value do
    configured_header_kvp_list = Application.get_env(:my_app, :csp_headers, [])

    @header_kvp_list
    |> Keyword.merge(configured_header_kvp_list)
    |> Enum.map_join("; ", &map_header_kvp_to_string/1)
  end

  defp map_header_kvp_to_string({atom_key, list_value}) do
    string_key = atom_key |> to_string() |> String.replace("_", "-")
    string_value = Enum.join(list_value, " ")
    "#{string_key} #{string_value}"
  end
end

That is lifted straight from one of my hobby projects. localhost:4007 is an imgproxy server.

Anyway, I think the thing that is needed is the google fonts bit? Not sure, but this solved heroicons for me in terms of CSP.


Edit 26 March 2024: read this instead: Blog Post: Content Security Policy header with Phoenix LiveView

2 Likes