I am pretty much familiar with the React.js
but new to Gatsby
.
I want to detect the previous page URL in Gatsby
?
I am pretty much familiar with the React.js
but new to Gatsby
.
I want to detect the previous page URL in Gatsby
?
You can pass down state using the Link
component:
import React from 'react';
import { Link } from 'gatsby';
const PrevPage = () => (
<div>
<Link
to={`/nextpage`}
state={{ prevPath: location.pathname }}
>
Next Page
</Link>
</div>
)
const NextPage = (props) => (
<div>
<p>previous path is: {props.location.state.prevPath}</p>
</div>
);
Then you have access to prevPath
from this.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 for window
object first:
class Page extends React.Component {
state = {
currentUrl: '',
}
componentDidMount() {
if (typeof window == 'undefined') return
this.setState({ currentUrl: window.location.href })
}
render() {
return (
<Link to="..." state={{ prevUrl: this.state.currentUrl }}>
)
}
}
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:
const SomePage = ({ location }) => (
<div>previous path is {location.state.prevUrl}</div>
);
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
.
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
to Page2
then the eg the state.prevUrl
will correctly be set to Page1
But if the you go to Page3
from Page2
and then do a browser back then the state.prevUrl
will still be Page1
which is false.
Best way I found to deal with this is to add something like this on the gatsby-browser.js
export const onRouteUpdate = ({ location, prevLocation }) => {
if (location && location.state)
location.state.referrer = prevLocation ? prevLocation.pathname : null
}
this way you will have always the previous url available on location.