I have a Liveview application that offers a Dark mode toggle. The setting is stored in browser localStorage and Dark mode is rendered via Hooks after the liveSocket is connected.
With the static HTML rendering in normal mode (dark mode disabled), for those who want to store their mode preferences between sessions, there is a distinctive visual transition between normal mode and dark mode, as the page first renders statically in normal mode, then re-renders in Dark Mode after the liveSocket connects.
Are there any good practices that can be applied to reduce or eliminate that visual transition distraction during initial page loading?
Update: The following article discusses how to use localStorage settings and insert them into the session so that the server can pass browser based settings on the first render. I will experiment with that potential solution. https://alex-min.fr/live-view-browser-timezone/
I was able to solve my dark mode rendering problem without needing to notify the server via a cookie, by changing app.js to examine the dark mode setting stored in localStorage and to change the DOM, as required, during initial load of app.js. Previously, I had that code in a Hooksmounted event in app.js
...
import {LiveSocket} from "phoenix_live_view"
let dark = localStorage.getItem("dark")
if (dark == null) {
dark = "false"
}
if (dark == "true") {
dark_mode(true)
} else {
dark_mode(false)
}
let Hooks = {}
Hooks.Dark = {
mounted() {
console.log("Dark hook id: " + this.el.id)
if (this.el.id == "dark") {
this.el.addEventListener("input", e => {
console.log("setting dark listener")
localStorage.setItem("dark", e.target.checked)
})
}
let dark = localStorage.getItem("dark")
if (dark == null) {
dark = "false"
}
if (dark == true) {
dark = "true"
}
this.pushEvent("restore", {
dark: dark,
})
},
updated() {
var dark_toggle = document.getElementById("dark")
console.log("dark_mode checked value: " + dark_toggle.checked)
if (dark_toggle.checked) {
dark_mode(true)
} else {
dark_mode(false)
}
}
}
In app.js at bottom:
function dark_mode(is_dark) {
var body = document.body
if (is_dark == true) {
body.classList.add("dark-mode")
} else {
body.classList.remove("dark-mode");
}
}