I'm using NextJS (v.13.4.15) app directory
I'm using a react-native webview to display a website inside of a mobile app, so a back button is critical for navigation (I cannot access the browser's back button)
I want something like
'use client' for client component:
<button
onClick={() => window.history.state && window.history.state.idx > 0 ? router.back() : router.push('/')}
>
However I cannot get this to work, NextJS seems to have issues with accessing window.history (or maybe it's not NextJS and it's just a privacy thing)
And even if I can access the window, the window object contains confusing and inconsistent children properties and values like this:
{
"__NA": true,
"tree": [
"",
{
"children": [
"courses",
{
"children": [
[
"slug",
"hacking-success",
"c"
],
{
"children": [
"__PAGE__",
{}
]
}
]
}
]
},
null,
null,
true
]
}
There has to be a way to check if (router.back()) is null or cannot go back, and then router.push('/) right?
ideally:
router.back() ?? router.push('/')
or can someone help explain this history.state.idx.tree? The length doesn't seem to match the number of history items from navigation, but rather the parent/hierarchy of the URL
I've wished that NextJS would have a method on the router that would return the history or provide a null/false value if the history is empty
However I've read the useRouter() documentation and no method seems to exist
I've tried to access the window.history object but cannot write code to check if history does not contain a path to navigate back to
My only other idea is to pass a parameter when linking to a "non home page" that can be checked and then conditionally change the back button logic based on the parameter, but that seems inefficient
This answer is close but also seems inefficient
Great question! Unfortunately this is one of the limitations of the browser history objects; it is not possible to get any information about what’s in it. This is especially troublesome if you’re making an app that’s either installable on the homescreen or, as you mentioned, as a webview inside a native mobile app, because eventually you’ll create external links, such as part of an email, that go directly to a subpage, and using goBack from what would normally go to the homepage will do something nasty (often it would show a blank page).
The only way to workaround this is by somehow tracking this yourself. My favorite solution is to track the URL-history manually within the app. This is a bit cumbersome, especially in Next.js (I don't think it's the best fit for a SPA).
I forgot in which projects I did this, so I have no ready-to-use code for you (sorry). The gist of the solution is that you need an array where you manually store all the routes the user visited. This has challenges though, since the user can go back and then the last history entry should disappear (pop) instead of being appended (push). To solve this, I used the history’s state object to store the history. The state object acts like (a hidden) part of a history object (which is basically a URL with extras). If you do navigations something like this:
history.push(‘/contact’, {
state: {
history: [
…this.router.state,
window.location.href,
],
},
})
The beautiful thing about the history state is that it is linked up with the URL (i.e. the page they’re on). That means if the user hits their back button, the previous state value will be restored automatically, so the manual history state will always match the browser’s history within your app.
With that setup, all you need to do to see if there’s a previous page in history is use history.state.history.length > 0.
Hopefully this is enough information to help you build a solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With