-
Notifications
You must be signed in to change notification settings - Fork 0
Description
[UX Ergonomics] Intercept browser back button to use live navigation instead
Context:
Currently, we have done the necessary live navigation methods that enable us to navigate through content without losing existing state for overlays.
However, this doesn’t work if the user simply clicks the back button on the browser which is probably the more ergonomic method for them anyway.
The solution to this should be simple, a hook is needed to add an event listener, then pass it to server side which does the pushpatch
here’s the quick perplexity outline of the task :
To intercept the browser's back button and perform a live navigation using push_patch
in a Phoenix LiveView application, you can utilize the popstate
event in JavaScript. This event is triggered whenever the active history entry changes, such as when the user clicks the back button.
Here's a step-by-step guide on how to achieve this:
Step 1: JavaScript to Intercept the Back Button
You can use JavaScript to listen for the popstate
event and trigger a LiveView event to perform a push_patch
.
document.addEventListener("DOMContentLoaded", function() {
window.addEventListener("popstate", function(event) {
// Prevent the default back button behavior
event.preventDefault();
// Trigger a LiveView event to handle the back navigation
liveSocket.execJS(document.body, `
LiveSocket.execJS(document.body, "phx-hook", "BackButtonHook", "handleBackButton")
`);
});
});
Step 2: Create a LiveView Hook
Create a LiveView hook that will handle the back button event and perform the push_patch
.
let Hooks = {}
Hooks.BackButtonHook = {
handleBackButton() {
// Perform a push_patch to navigate to the desired URL
this.pushEvent("back-button", {})
}
}
Step 3: Handle the Event in LiveView
In your LiveView module, handle the back-button
event to perform a push_patch
.
defmodule MyAppWeb.MyLiveView do
use Phoenix.LiveView
def mount(_params, _session, socket) do
{:ok, socket}
end
def handle_event("back-button", _params, socket) do
# Define the URL you want to navigate to
new_url = "/desired-path"
# Perform a push_patch
{:noreply, push_patch(socket, to: new_url)}
end
end
Explanation
-
JavaScript
popstate
Event: This event is triggered when the active history entry changes. By listening to this event, you can intercept the back button action. -
LiveView Hook: The
BackButtonHook
is a custom hook that handles the back button event and triggers a LiveView event. -
LiveView Event Handling: The
handle_event/3
function in your LiveView module handles theback-button
event and performs apush_patch
to navigate to the desired URL.
Considerations
-
User Experience: Intercepting the back button can lead to unexpected behavior for users, so ensure that this approach aligns with your application's user experience goals.
-
Browser Compatibility: Test this implementation across different browsers to ensure consistent behavior.
This setup allows you to intercept the back button and perform a live navigation using push_patch
, providing a seamless user experience in your Phoenix LiveView application.
Citations:
[1] https://stackoverflow.com/questions/1844491/intercepting-call-to-the-back-button-in-my-ajax-application
[2] https://www.bennadel.com/blog/3533-using-router-events-to-detect-back-and-forward-browser-navigation-in-angular-7-0-4.htm
[3] https://stackoverflow.com/questions/12381563/how-can-i-stop-the-browser-back-button-using-javascript/45211382
[4] https://www.reddit.com/r/react/comments/16e3c44/trying_to_figure_out_a_way_to_override_browser/
[5] vercel/next.js#2694
[6] https://hexdocs.pm/phoenix_live_view/live-navigation.html
[7] https://hexdocs.pm/phoenix_live_view/0.15.4/live-navigation.html
[8] https://discuss.hotwired.dev/t/browser-back-button-not-working/5741