Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserving Web Component state with hx-preserve on browser navigation #2531

Open
jasontheiler opened this issue May 5, 2024 · 1 comment

Comments

@jasontheiler
Copy link

Hi everyone,

I'm trying to create a website with HTMX and its hx-boost feature. Since I want to avoid using another frontend framework, I'm trying to use Web Components for elements that have some logic and state associated with them. With the hx-preserve attribute and an ID I can preserve a Web Component's state across page navigations. However, if one uses the browser's built-in back and forward navigation, the Web Components lose all of their state and they get newly instantiated.

I have searched the internet and the HTMX issues for a solution, but I have trouble finding useful information about this specific use case.

I've created a simple reproduction on CodeSandbox with a simple counter as a Web Component that keeps its count across page navigations using the links at the top in the header. As soon as you use the browser's back and forward navigation though, the counter resets back to 0.

I'd be really grateful for any help on the matter!

@jasontheiler
Copy link
Author

Okay, so I found out that other SPA routers are simply overriding the browser's window.onpopstate callback function to manipulate the DOM manually. And you can obviously do that, too, and then simply call htmx's ajax() function to mimic the behavior of hx-boost, like so:

window.onpopstate = () => htmx.ajax("GET", window.location.pathname);

I created another CodeSandbox example with this solution for demonstration purposes.

Another approach I found is to use the experimental Navigation API. Using this, it is possible to drop hx-boost entirely and just listen to the navigate event of this API, like so:

window.navigation.addEventListener("navigate", (event) => {
    if (!event.canIntercept || event.hashChange || event.downloadRequest !== null) {
        return;
    }

    event.intercept({
        async handler() {
            const url = new URL(event.destination.url);
            await htmx.ajax("GET", url.pathname);
        },
    });
});

However, as of right now the Navigation API is not supported by Firefox and Safari. So it's only really an option in the future.

Now, the solution to this problem isn't complicated, but it actually wasn't that easy to find (at least for me), so it may be nice to have this functionality built into htmx in some form or another or at least have the docs mention it somewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant