StephD
StephD

Reputation: 304

highlight active page link in React/Gatsby

Not using React Router here, would like to keep it simple. I'm using Gatsby which has an activeClassName attribute with its <Link> system, however, I think it's not working because I'm using it on a main nav, then I have a subnav with categories.

The solution I came up for the subnav is a little function to see if you're in a directory:

  const activeStyle = {
    color: "green",
    background: "red",
  }
  function pathIncludes(word) {
    return window.location.href.includes(word) ? { activeStyle } : ""
  }

and then inside my return():

<ul>
    <li styles={pathIncludes('motion')}>
        <Link to="./motion">Motion</Link>
    </li>
    <li styles={pathIncludes('design')}>
        <Link to="./design">Design</Link>
    </li>
    <li styles={pathIncludes('illustration')}>
        <Link to="./illustration">Illustration</Link>
    </li>
</ul>

It almost works, rendered on the page I get <li class="[object Object]">

How can I pass it the jsx?

Or, is there a better way to do this, that doesn't involve installing extra dependencies?

Upvotes: 0

Views: 2351

Answers (2)

bebyx
bebyx

Reputation: 150

I tried the accepted reply, it works fine for URLs having path tails (example.com/about) but doesn't work for home pages (example.com/).

I lurked a bit and found much more elegant solution which makes use of native Gatsby's <Link> getProps prop (read @reach/routes documentation for more).

So, if we add a home page to your example (even if not, it still seems to be more appropriate way to style the active links), the solution will look like this:

function isActive( {isCurrent} ) {
    return isCurrent ? {className: "active"} : null
}

<ul>
  <li>
    <Link to="/" getProps={isActive}>Home</Link>
  </li>
  <li>
    <Link to="/design" getProps={isActive}>Design</Link>
  </li>
  <li>
    <Link to="/illustration" getProps={isActive}>Illustration</Link>
  </li>
</ul>

Upvotes: 3

Michael
Michael

Reputation: 958

I think the problem are the brackets {} around activeStyle in the line

return window.location.href.includes(word) ? { activeStyle } : ""

They act as destructuring activeStyle which is an object. But style expects an object. So

return window.location.href.includes(word) ? activeStyle : "" `

should work.

Upvotes: 2

Related Questions