Gatsby: How can I get the current url (or path) in a page in v2

Created on 4 Oct 2018  Â·  7Comments  Â·  Source: gatsbyjs/gatsby

Summary

Hi there, I'm trying to create an og:url property, which requires the current page URL in the head tag. I have everything wired up, except the part where I can determine the current location of the page itself.

Relevant information

@skjorrface location is passed to the layout as a prop (the pages will receive it in V2), so if you're using it from a component you'd need to pass it down:

const Layout = ({ location }) => (
  <MyComponent location={location} />
);

Does that make sense?
— @jlengstorf, https://github.com/gatsbyjs/gatsby/issues/1875#issuecomment-420811319

Unfortunately, calling this.props.location.pathname in my index.js file didn't help and it stopped. I'm wondering if something before the stable release and wasn't documented?

awaiting author response question or discussion

Most helpful comment

@amingilani functional components don't have a this prop, so you'd need to do this instead:

const IndexPage = (props) => (
  <Layout location="/" noHeader="true">
    <p>This won't work at all {props.location.pathname}</p>
  </Layout>
)

Another option is to use the Location import from @reach/router. I put together a CodeSandbox example to show how that works.

The index.js page uses the Location provider, and the page-2.js page uses props.location.

Let me know if that doesn't get you up and running.

All 7 comments

What data is on this.props?

@KyleAMathews here's a dumb question, how do I peek inside?

Everytime I run console.log(this.props), it just stops rendering, and I get:

:8000/Users/gilani/Sandbox/amingilani.github.io/node_modules/react-hot-loader/dist/react-hot-loader.development.js:1 Failed to load resource: the server responded with a status of 404 (Not Found)

Hmmm not sure what that means. Are you using a class component?

Hmmm not sure what that means. Are you using a class component?
@KyleAMathews, no, I'm using a functional component.

Sighhh, update, I peeked through React Developer Tools.

screen shot 2018-10-04 at 9 25 26 pm

I should be getting props, but for some reason calling this.props makes the whole thing hang. For example, the page renders fine with this code:

This works

Note: The footer is rendered by the Layout component

const IndexPage = () => (
  <Layout location="/" noHeader="true">
    <p>This works fine</p>
  </Layout>
)

screen shot 2018-10-04 at 9 29 53 pm

This doesn't work

const IndexPage = () => (
  <Layout location="/" noHeader="true">
    <p>This won't work at all {this.props.location.pathname}</p>
  </Layout>
)

screen shot 2018-10-04 at 9 32 38 pm

@amingilani functional components don't have a this prop, so you'd need to do this instead:

const IndexPage = (props) => (
  <Layout location="/" noHeader="true">
    <p>This won't work at all {props.location.pathname}</p>
  </Layout>
)

Another option is to use the Location import from @reach/router. I put together a CodeSandbox example to show how that works.

The index.js page uses the Location provider, and the page-2.js page uses props.location.

Let me know if that doesn't get you up and running.

Thanks @jlengstorf, this works perfectly!

@jlengstorf: thanks for that example! BTW, page-2.js had an unused import { Location } from '@reach/router'.

To clarify, location is passed to the SecondPage component because it's a page component. Non-page components don't automatically get a location.

A simpler way to access the location than the Location HOC is to use the useLocation() hook:

const { href, pathname } = useLocation();

Here is an updated demo showing that non-page components don't receive location via props, but can easily get it with the useLocation() hook.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dustinhorton picture dustinhorton  Â·  3Comments

dustinhorton picture dustinhorton  Â·  3Comments

andykais picture andykais  Â·  3Comments

mikestopcontinues picture mikestopcontinues  Â·  3Comments

theduke picture theduke  Â·  3Comments