How do I get the current url in Gatsby?

If like me, you just wanted to know how to get a uri 'for a component' and this whole issue confused you because of the general complexity of the solutions and documentation out there compared to that simple need, another way that does not involve understanding reach router (which is a nice thing to understand but a bit heavy for simply getting the uri at build time) is to pass your location as a prop from a page. This works well if you want to use the uri for things like setting defaultActiveKey on bootstrap menus where the menu itself it not the only way to access that page and so "activeClassName" does not always work. It also works at build time. Whatever, it gives you access to the uri in a component.

I don't think this will work for headless CMS type implementations but there are other ways of dealing with that.

If you haven't used props much before then these are things you can pass around your pages and components (simplification) and I would recommend you look up how to use them. By default in Gatsby, pages have a location pathname property so you can tell your component about that location from the calling page by passing it as a prop. In English, this would be 'Use this component with its location set to the property "location.pathname" of me, the calling page". The component now has the location.

What you need to do is create a page like so

import React from "react"
import NavComponent from "../../components/navComponent"

const APage = (props) => {
  return (
     <NavComponent location={props.location.pathname}/>
  )
}
export default APage

For the hard of thinking (like me), the location={props.location.pathname} bit means that in the component, your props will now have a location value and it will be set to the location.pathname of the page that called it. Therefore, in your Nav component you now have access to the uri. Remember that to get it, your component needs to receive props before it can use them. The result is something like so (pointless to do this but it gives the idea).

import React from "react"

const NavComponent = (props) => {
  return (

        <Nav data-uri={props.location}>
        </Nav>  

  )
}

export default NavComponent

When you are on APage then data-uri will be whatever that is for APage and on BPage, whatever it will be for that.


You can use useLocation like p.boiko suggested like so:

import * as React from 'react';
import { useLocation } from '@reach/router';

const UserTheme = () => {
  const location = useLocation();
  console.log(location)  
};

Output would be:

{pathname: "/", search: "", hash: "", href: "http://localhost:8000/", origin: "http://localhost:8000", …}

You can get the current url using the location prop from the @reach/router Location component.

import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { Location } from '@reach/router';

class SomeComponent extends Component {
  static propTypes = {
    location: PropTypes.object.isRequired
  }

  render() {
    const { location } = this.props;
    return <div>{JSON.stringify(location)}</div>;
  }
}

export default props => (
  <Location>
    {locationProps => <SomeComponent {...locationProps} {...props} />}
  </Location>
);

Gatsby uses react-router behind the scene meaning location information is available in props. This information can be used in a conditional statement or passed into styled-components like so:

<Component isIndex={this.props.location.pathname === '/'}>

Tags:

Gatsby