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
2 Likes
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.
1 Like
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.
2 Likes