Kai Qing
Kai Qing

Reputation: 18843

Browser back button not working for gatsby.js project

Anyone know what would cause the back button to not work when using standard Link tags in a gatsby project?

The url changes but the route doesn't update.

This is a gatsby source wordpress project if that helps to know. All wp pages are made with the createPage method, and everything appears to work as expected.

Conversely, I have another gatsby project that does not use the wordpress source. On that project the browser back and forward buttons work fine. So clearly it's not that gatsby itself breaks this by default. But in my inspections I cannot see a fundamental reason why the two projects configurations or anything else would cause this. They're almost identical except the source wordpress part.

Anyone else come across something like this?

Upvotes: 3

Views: 2880

Answers (3)

rodrigogiraudo
rodrigogiraudo

Reputation: 11

I had the same problem in my project but not for every link. I tried to apply the solutions here mentioned but it had the drawback that when going back it reloaded everything. I continued researching and found something, crazy, but worked.

Let me know if this worked for you.

I am using a WordPress site as a source. I was doing:

<Link to={`/help/${node.slug}/`}>{node.title || null}</Link>

I fixed it by removing the last / from the source. Like this:

<Link to={`/help/${node.slug}`}>{node.title || null}</Link>

Upvotes: 0

Lexis Hanson
Lexis Hanson

Reputation: 857

I've been running into this issue as well. It's been such a hassle to get down to the root cause.

I'd recommend also checking out this GitHub issue, where another workaround is proposed.

@gurpreetatwal suggests adding this to gatsby-browser.js:

import {globalHistory} from '@reach/router';
export const onInitialClientRender = () => {
  /**
   * This is a workaround for a bug in Gatsby
   *
   * See https://github.com/gatsbyjs/gatsby/issues/8357 for more details
   */
  globalHistory._onTransitionComplete();
}

Per his explanation there is likely an issue with @reach/router and Gatsby, where a transitioning state is set to true and causes @reach/router to replace history instead of push to history. onTransitionComplete is only called in the onComponentDidUpdate of @reach/router, which isn't often called on navigation. I'll defer to the issue for more explanation and updates.

What I've deduced is that this fix enables the calling of _onTransitionComplete() and allows for pushing onto history when the page changes.

I tried your solution as well as @gupreetatwal's. The key benefit of @gupreetatwa solution is that it won't cause a full-page refresh. Still feels like a hack for now, but it's at least another route to try.

This issue cost us days, so hoping this saves others some time.

Upvotes: 3

Kai Qing
Kai Qing

Reputation: 18843

Ok so, for anyone else experiencing this - no doubt your googling has driven you to madness. How can we be the only ones who have dealt with this? Indeed, infuriating.

Fret not, there is a hack. And yeah, I'm sure it's a total hack.

In your gatsby-browser.js file, add this:

exports.onInitialClientRender = () => {
  window.addEventListener('popstate', () =>
    window.location.href = window.location.href
  )
}

WTF is this doing, you ask? It's forcing the url to redirect to itself. Sounds MORONIC, right? It is, except that this only fires when you use the browser's navigation. Problem solved, right? No, not really. Problem is masked. But for me, that is good enough until someone has an actual answer.

Why does this solution suck? Because it breaks the concept of a SPA. You're no longer single page if you force a reload in there. For me, I am not too concerned only because this happens only on back and forward button clicks. But if this were a $50k client, I am positive my little hack wouldn't fly with them.

If anyone has an actual Gatsby solution that doesn't break the SPA model, post it here and I will gladly transfer accepted answer to you. Till then... hack on.

Upvotes: 3

Related Questions