Gatsby will throw error during production build, since location is not available during server-side rendering. You could get around it by checking for window object first:
But this requires us to implement this on every page, which is tedious. Gatsby has already set up @reach/router for server-side rendering, so we can hook into its location props. Only router components get that props, but we can use @reach/router's Location component to pass it to other components.
With that, we can write a custom Link component that always pass previous url in its state:
// ./src/components/link-with-prev-url.js
import React from 'react'
import { Location } from '@reach/router'
import { Link } from 'gatsby'
const LinkWithPrevUrl = ({ children, state, ...rest }) => (
<Location>
{({ location }) => (
//make sure user's state is not overwritten
<Link {...rest} state={{ prevUrl: location.href, ...state}}>
{ children }
</Link>
)}
</Location>
)
export { LinkWithPrevUrl as Link }
Then we can import our custom Link component instead of Gatsby's Link:
- import { Link } from 'gatsby'
+ import { Link } from './link-with-prev-url'
Now each Gatsby page component will get this previous url props:
You might also consider creating a container that store state for the client side & use the wrapRootElement or wrapPageElement in both gatsby-ssr.js and gatsby-browser.js.
You can pass down state using the
Link
component:Then you have access to
prevPath
fromthis.props.location.state
in the next page.Full credit to @soroushchehresa's answer — this answer is just extras built upon it.
Gatsby will throw error during production build, since
location
is not available during server-side rendering. You could get around it by checking forwindow
object first:But this requires us to implement this on every page, which is tedious. Gatsby has already set up
@reach/router
for server-side rendering, so we can hook into itslocation
props. Only router components get that props, but we can use@reach/router
'sLocation
component to pass it to other components.With that, we can write a custom Link component that always pass previous url in its state:
Then we can import our custom Link component instead of Gatsby's Link:
Now each Gatsby page component will get this previous url props:
You might also consider creating a container that store state for the client side & use the
wrapRootElement
orwrapPageElement
in bothgatsby-ssr.js
andgatsby-browser.js
.These answers are partially correct. If you set state using link api then the state persists in browser history.
So if you go from
Page1
toPage2
then the eg thestate.prevUrl
will correctly be set toPage1
But if the you go to
Page3
fromPage2
and then do a browser back then thestate.prevUrl
will still bePage1
which is false.Best way I found to deal with this is to add something like this on the gatsby-browser.js
this way you will have always the previous url available on location.