kokolegorille

kokolegorille

Hello everyone,

I am trying to implement live reload on a static page, for an API.

I build the project with --no-html --no-webpack, and added a bucklescript pipeline instead.

There is only one page, a static index.html, located in priv/static. I render with the following action

  def index(conn, _params) do
    conn
    |> put_resp_header("content-type", "text/html; charset=utf-8")
    |> IO.inspect()
    |> send_file(200, "priv/static/index.html")
  end

I added phoenix-live-reload, configured the api to use it… and now code is reloading when frontend files change. I can see bsb and webpack reloading in the background.

I have configured my Endpoint with live/code reload, and I can see in my connection when in development.

  before_send: [#Function<1.112466771/1 in Plug.Logger.call/2>, 
   #Function<0.66982185/1 in Phoenix.LiveReloader.before_send_inject_reloader/2>],

But as it is an api only, there is no phoenix_html, I need to inject the live reload iframe manually into the static index.html.

Can somebody point me where (and when) Phoenix inject the live reload iframe? I find it hard to find in the source code.

Thanks for taking time

Marked As Solved

kokolegorille

kokolegorille OP

The code is in the live_reloader, as said by @dom, in the private functions…

At the very end, we can find

  defp before_send_inject_reloader(conn, endpoint) do
    register_before_send(conn, fn conn ->
      if conn.resp_body != nil && html?(conn) do
        resp_body = IO.iodata_to_binary(conn.resp_body)
        if has_body?(resp_body) and :code.is_loaded(endpoint) do
          [page | rest] = String.split(resp_body, "</body>")
          body = page <> reload_assets_tag(conn) <> Enum.join(["</body>" | rest], "")
          put_in conn.resp_body, body
        else
          conn
        end
      else
        conn
      end
    end)
  end

  defp reload_assets_tag(conn) do
    path = conn.private.phoenix_endpoint.path("/phoenix/live_reload/frame")
    """
    <iframe src="#{path}" style="display: none;"></iframe>
    """
  end

The solution is dead simple (once You get how it works), Not even the need to parse the static file, just render with.

  def index(conn, _params) do
    file = "priv/static/index.html"
    {:ok, binary} = File.read(file)
    html(conn, binary)
  end

The html helper will take care of this. Sorry for the question…

Now I have a slim api, with live reload enable on the static file.

Also Liked

kokolegorille

kokolegorille OP

Thank You for the response, but I read this and configured accordingly…

It does set the before_send in my connection correctly.

But I would like to know where this function is applied in reality (the plug just add a function in the before_send). As it is a static file, not an eex template, I will need to inject manually.

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
ChrisAmelia
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication): toke...
New
dillonoconnor
Is there any way to avoid the Hologram compiler running when using iex? It seems like the front-end code could potentially be disregarded...
New
thiagogsr
** (ArgumentError) expected :max_attempts to be a positive integer, got: {:@, [line: 10, column: 19], [{:max_attempts, [line: 10, column:...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews