Alpine3 + Phoenix 1.6.6: JS blinks

Testing Alpinejs 3.9.1 and phoenix 1.6.6. When I load a non LiveView page, Alpinejs works, while not on a LiveView page.

Example:

  • get "/home", PageController, :index serves “/templates/page/index.html.heex” which contains <p x-data="{message: 'yes'}" x-text="message">no</p>. It can see “yes” on page load.

  • live "/", PageLive serves “/live/page_live.html.heex” which contains the same code, <p x-data="{message: 'yes'}" x-text="message">no</p>. On page load, when alpinejs is imported in “assets/js/apps.js”, I start to see “yes” and then eventually “no”.

  • when I add the CDN script below in “templates/layout/root.html.heex”, I see the reverse: page load starts with “no” and eventually I get “yes”.

<script 
  src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"
  defer
></script>

Any experience on this?

#package.json
"devDependencies": { "alpinejs": "^3.9.1",...}
#assets/js/apps.js
import Alpine from "alpinejs";
window.Alpine = Alpine;
Alpine.start();
[...]
let liveSocket = new LiveSocket("/live", Socket, {
  params: { _csrf_token: csrfToken },
  dom: {
    onBeforeElUpdated(from, to) {
      if (from.__x) {
        window.Alpine.clone(from.__x, to);
      }
    },
  },
});
iex> MyApp.MixProject.project[:deps]
[
  {:phoenix, "~> 1.6.6"},
  {:phoenix_ecto, "~> 4.4"},
  {:ecto_sql, "~> 3.6"},
  {:postgrex, ">= 0.0.0"},
  {:phoenix_html, "~> 3.0"},
  {:phoenix_live_reload, "~> 1.2", [only: :dev]},
  {:phoenix_live_view, "~> 0.17.5"},
  {:floki, ">= 0.30.0", [only: :test]},
  {:phoenix_live_dashboard, "~> 0.6"},
  {:esbuild, "~> 0.3", [runtime: true]},
  {:swoosh, "~> 1.3"},
  {:telemetry_metrics, "~> 0.6"},
  {:telemetry_poller, "~> 1.0"},
  {:gettext, "~> 0.18"},
  {:jason, "~> 1.2"},
  {:plug_cowboy, "~> 2.5"}
]
1 Like

Are you using phx-update="ignore"?

Does it have an id?

3 Likes

No! But I tried it. Now, it works without the CDN (just the import in the “assets/js/app.js” file), To avoid the transition blink from “no” to eventually “yes”, I should use the x-text directive (doesn’t work without) and leave the innerText blank.

<p  phx-update="ignore" x-data="{msg: 'yes'}" x-text="msg"></p>

Thanks

1 Like

Yeah, it won’t change until Alpine is initialized.

FWIW, I find it easier/cleaner/less janky to use hooks if there is some sort of state kept in the frontend. Ripped out a bunch of my buggy Alpine mess over the weekend in favour of JS commands and tiny hooks. Very happy with the final product.

1 Like