1

I'd like to import different CSS depending on which page I'm on. The HTML will stay the same. What do I need to do to access the current location?

I was thinking I could put an if statement in the constructor and import the CSS there, but I'm not sure that will work.

EDIT: you can't import from within the constructor, so is there a way to do a conditional import?

Here's my code:

import React from 'react'
import Link from 'gatsby-link'


class Menu extends React.Component {

    constructor(props) {
        super(props)

        //how do I get myCurrentLocation?
        if(myCurrentLocation == '/') {
            import menuStyle from '../page-assets/global/styles/menu/_home-page.sass'
        } else {
            import menuStyle from '../page-assets/global/styles/menu/_regular-page.sass'
        }
    }

    render (){
        return (
            <nav className="menu">
                <Link to="/work-ive-done/" className="menu-item">
                    <span className="menu-item__heading">
                        Work
                    </span>
                    <span className="menu-item__sub-text">
                        ive done
                    </span>
                </Link>

                //other menu items ...

            </nav>
        )
    }
}

export default Menu;
Eric Johnson
  • 1,084
  • 13
  • 24

2 Answers2

2

gatsby-link is a wrapper for react-router-dom Link, so you should be able to access your route by using this.props.match.path.

otherwise: You can access your current url using window.location.href

https://developer.mozilla.org/en-US/docs/Web/API/Window/location

C.Q
  • 48
  • 5
  • This is helpful! I'll see if I can access that `this.props.match.path` – Eric Johnson Jan 04 '18 at 20:12
  • I'm not able to access `this.props.match.path` in the `render()` or `constructor()` functions. Should it be available in that scope? – Eric Johnson Jan 04 '18 at 20:49
  • Where are you rendering your menu component? If it is within a route component, then you can pass those props down to menu. – C.Q Jan 04 '18 at 22:05
  • Ah, duh, that was it. Sorry, my React is pretty rusty! – Eric Johnson Jan 04 '18 at 22:16
  • Turns out `this.props.location.pathname` was the ticket. `this.props.match.path` seemed to only have `/` in it regardless of the page I was on. But I'm using Gatsby's default router where it makes routes out of whatever pages you have in the `pages` directory, so maybe it doesn't populate `this.props.match.path`. – Eric Johnson Jan 09 '18 at 14:56
1

In Gatsby v2, the page components will be able to access their location through the following:

  • for class components: this.props.location.pathname
  • for functional components: props.location.pathname

For function components, ensure props are being passed through their params. e.g.

const IndexPage = (props) => (
  <Layout>
    <p>This works {props.location.pathname}</p>
  </Layout>
)

For anywhere else, you can use @reach/router's Location component (credits: jlengstorf)

import React from 'react';
import { Location } from '@reach/router';

export default () => (
  <Location>
    {({ navigate, location }) => /* ... */}
  </Location>
);

Here's a codesandbox showing the above. Also credits jlengstorf .

Amin Shah Gilani
  • 8,675
  • 5
  • 37
  • 79
  • props.location.pathname works well in development, but in production, once I push to github pages, it works well just on the first load. After the service workers starts, it doesn't work anymore. But it's very weird, cause if I output the value, it does return it... I'm baffled. – Joan Mira Jan 17 '19 at 16:29
  • @JoanMira I'd file an issue for this behavior. They're definitely helpful and would be interested in this behavior. – Amin Shah Gilani Jan 18 '19 at 17:41