Gatsby: Setting activeClassName on page load

Created on 21 Aug 2018  路  19Comments  路  Source: gatsbyjs/gatsby

Description

Using the latest beta of Gatsby 2, I am using activeClassName on the link component to style selected links. When clicking on a link and navigating to a new page, this works fine. But if I refresh the page, the class is not applied to the link pointing to the page that I just refreshed. I鈥檝e been able to replicate on two different sites.

This only happens on production builds, not when running the site locally.

Steps to Reproduce

  1. Go to a page that has a link to itself within the page.
  2. Refresh the page
  3. Observe that the active class is not applied to the link.

Expected result

The proper class name is added to the link.

Actual result

The class is not applied.

Environment

Will add this when I am back on my computer (submitting this from mobile).

  System:
    OS: macOS 10.14
    CPU: x64 Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 8.9.0 - ~/.nvm/versions/node/v8.9.0/bin/node
    Yarn: 1.9.4 - ~/.yarn/bin/yarn
    npm: 6.1.0 - ~/.nvm/versions/node/v8.9.0/bin/npm
  Browsers:
    Chrome: 68.0.3440.106
    Firefox: 61.0.2
    Safari: 12.0
  npmPackages:
    gatsby: ^2.0.0-beta.112 => 2.0.0-beta.112 
    gatsby-plugin-catch-links: ^2.0.2-beta.10 => 2.0.2-beta.10 
    gatsby-plugin-favicon: ^3.1.2 => 3.1.2 
    gatsby-plugin-google-analytics: next => 2.0.0-beta.5 
    gatsby-plugin-react-helmet: next => 3.0.0-beta.4 
    gatsby-plugin-sass: next => 2.0.0-beta.10 
    gatsby-plugin-styled-components: next => 3.0.0-beta.3 
    gatsby-plugin-typography: next => 2.2.0-beta.3 
    gatsby-remark-autolink-headers: ^1.4.18 => 1.4.19 
    gatsby-remark-component: ^1.1.3 => 1.1.3 
    gatsby-remark-copy-linked-files: next => 2.0.0-beta.3 
    gatsby-remark-external-links: ^0.0.4 => 0.0.4 
    gatsby-remark-smartypants: next => 2.0.0-beta.3 
    gatsby-source-filesystem: next => 2.0.1-beta.10 
    gatsby-transformer-remark: next => 2.1.1-beta.6 
  npmGlobalPackages:
    gatsby-cli: 2.0.0-beta.13
needs more info

Most helpful comment

This still doesn't work for me, I still lose the active class on page refresh.
Works only on my index page.

All 19 comments

Try using exact={true} inside the Link tag. This works, can someone explain why?

@haxzie The exact prop has been deprecated per https://next.gatsbyjs.org/docs/migrating-from-v1-to-v2/#the-following-props-are-no-longer-available-on-link

Can you post a link to a reproduction?

@KyleAMathews I'll try to make one soon (this is a work project so I can't send you the actual thing 馃槖). I did just realize though that this only appears to be happening in production, not when running locally.

I am prefixing paths in production, maybe that has something to do with it?

Try using:

const isActive = ({ isCurrent }) => {
  return isCurrent ? { className: "active" } : null
}

const ExactNavLink = props => (
  <Link getProps={isActive} {...props} />
)

https://reach.tech/router/api/Link

Since activeClassName is from react-router-dom.

@azdanov The Link component in Gatsby still supports activeClassName.

This could be caused by #7528, which seems to be a similar bug that only happens in production.

Also encountering this, can someone solve this issue?

As @chasemccoy mentioned this could be because of the extra slash. If I console.log the props given by getProps like this:

<Link
  getProps={props => {
    console.log(props)

    return null
  }}
  {...rest}
/>

and run gatsby build I get path names with extra slash at the beginning

selection_008

I don't know the reason behind double slashes but I think it messes up the isCurrent checking.

There are a couple of PRs open already to fix this. Check out #7641 and #7577

I am noticing this issue was well. However, if you inspect the links in React Dev tools they show as having the class applied but it's not updating in the DOM.

@chasemccoy can you confirm whether [email protected] has fixed this for you?

@m-allanson Yep, confirmed that this fixed it! Thanks!

This still doesn't work for me, I still lose the active class on page refresh.
Works only on my index page.

@PHurst1 as a workaround, add the trailing slash manually:

Before:

to={path}

After:

to={`${path}/`}

Adding the slash like that manually seems to work in 2.19.17

@abuuzayr's solution fixed the on-load issue for me - thanks! 馃憤

You can add partiallyActive={true} to <Link> element to avoid adding the trailing slash (2.1.31<).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rossPatton picture rossPatton  路  3Comments

signalwerk picture signalwerk  路  3Comments

ghost picture ghost  路  3Comments

benstr picture benstr  路  3Comments

dustinhorton picture dustinhorton  路  3Comments