Skip to content

[UX] Intercept browser back button to use live navigation instead #89

@rtshkmr

Description

@rtshkmr

[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 the back-button event and performs a push_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

Metadata

Metadata

Assignees

Labels

lift.lowIndicates that the expected lift for it is lowpriority.highHigh urgency, high impact -- Priority is the intersection of impact and urgency.type.UXInvolves UX work, that improves the user's experience

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions