The team is now working on the WordPress Interactivity API. This unblocks the same UX Frontity framework enabled but directly in WordPress Core, fully compatible with the new Site Editor.
The param title seems to be ignored by most browsers, so I think we should not pass it down to the browser as it may lead to confusion. But we can store it.
User Stories
As a Frontity developer
I want to use the replace method (instead of push)
so that update the most recent entry on the history stack
As a Frontity developer
I want to populate the state and title of each history entry
so that I can recover that state in Frontity when the user moves around
Possible solution
Initial proposed solution (click to open)
Add a second parameter to actions.router.set for these options.
actions.router.set("/a-url");
actions.router.set("/new-url", {
method: "push",
title: "Some title",
state: {
someState: "that I want to save",
},
});
actions.router.set("/other-url", {
method: "replace",
title: "Some other title",
state: {
otherState: "that I want to save",
},
});
Maybe we can use state.router.historyState instead of state.router.state? Does it make sense? It would provide more info than just calling it state, which besides being repetitive might also be confusing.
luisherranz3
Hmm⦠thatās a good point.
What if we end up adding a state.router.history array in the future? Would having:
state.router.historyState
state.router.history[0].state
be confusing?
Shit, naming is hard
We also have the same problem with title, which also belongs to the browser history. For consistency both should be named in the same manner.
Iām adding url for consistency and Iām calling it browserHistory to:
Make it more clear that this is related to the window.history.
Leave state.router.history for a possible array of URL changes controled by us.
1 Like
orballo4
state.router.browserHistory sounds good to me.
orballo5
Iām a bit confused now, so I guess other users might be as well if they come to use this api. Is browserHistory editable or a read-only object? I mean, that as a user I might think that updating that part of the state is going to update the window.history.
EDIT:
It is more confusing to me that the browserHistory doesnāt exactly map to window.history.
One more thing: Iād avoid exposing the title field in the frontity api. As itās not used, Iād just internally set title to empty string in order to prevent any future bugs, but thatās it.
So my final API would look something like:
actions.router.set("/some-url", {
method: "push",
state: {
someState: "useful data to save",
},
});
state.router.link = "/current-url";
state.router.browserHistoryState = {
someState: "useful data to save",
};
// or
state.router.windowHistoryState = {
someState: "useful data to save",
};
luisherranz7
Yes because that would match state.router.history, but I agree that it is confusing.
If we get rid of title, then using an object doesnāt make sense.
We will certainly end up introducing state.router.history sooner or later, so what about:
actions.router.set("/some-url", {
method: "push",
state: {
someState: "useful data to save"
}
});
state.router.link; // <- last link
state.router.method; // <- last method
state.router.state; // <- last state
state.router.history = [
{
link: "/some-url",
method: "push",
state: { someState: "useful data to save" }
}
];
And we live with state.router.state
1 Like
orballo8
Iām fine with this. Should the history be implemented on this issue or just the state?
luisherranz9
Only state and method.
orballo10
I had doubts on what the state object stored in window.history should look like, because it was used to store the initial state.router.link and that link was used to update the state when popstate event was fired, i.e. when the user navigated back or forward though the history.
I decided to implement it in a way that what you get from window.history.state is exactly the same object you get from state.router.state, therefore removing the link field, and using window.location instead to update the app state when a popstate event fires.
In addition to this, I wasnāt sure to what value state.router.method should store after a popstate event. The options where to store the original method in window.store.state and restore that value, or actually store pop and making it clear this way that we arrived to the current state because the user moved through history.
I decided that the most useful info would be to store pop, because knowing the original method used to create that state didnāt seem to provide any useful information. So the values that can be found in state.router.method would be 'push' | 'replace' | 'pop'.
I might be wrong, so please go through the PR and let me know what you think and if I should make any changes.
luisherranz11
Maybe storing state.router.method makes no sense and we have to leave that for state.router.history.
What do you think? I canāt imagine a use case now for it.
orballo12
I couldnāt either, I left it there because I thought you had something in mind
luisherranz13
No, sorry. I guess I was still thinking about state.router.history where it does make sense
1 Like
luisherranz14
Pull Request
Final implementation
Now the action actions.router.set accepts an optional options object as the second argument:
state: An object that is saved in window.history. It will be recovered when the user navigates between different URLs with the Back and Forward button of the browser. The default is an empty object {}.
The state object passed in the options is saved in state.router.state.
The new method: "replace" option is useful to replace the current URL of the app, without creating a new entry in the history. It is particularly useful when you want to update the URL (or state object) of the current history entry in response to some user action that has changed the current URL but itās not perceived that way, like an infinite scroll or a swipe.
@orballo feel free to add more things if I missed something.