Note that this is for React Router v4/5, for v2/3 see this solution.
Demo website (code on the gh-pages
branch)
This is a solution to React Router's issue of not scrolling to #hash-fragments
when using the <Link>
component to navigate.
When you click on a link created with react-router-hash-link
it will scroll to the element on the page with the id
that matches the #hash-fragment
in the link. This will also work for elements that are created after an asynchronous data load. Note that you must use React Router's BrowserRouter
for this to work.
$ yarn add react-router-hash-link
# OR
$ npm install --save react-router-hash-link
// In YourComponent.js
...
import { HashLink } from 'react-router-hash-link';
...
// Use it just like a RRv4/5 <Link> (to can be a string or an object, see RRv4/5 api for details)
<HashLink to="/some/path#with-hash-fragment">Link to Hash Fragment</HashLink>
// In YourComponent.js
...
import { NavHashLink } from 'react-router-hash-link';
...
// Use it just like a RRv4/5 <NavLink> (see RRv4/5 api for details)
// It will be active only if both the path and hash fragment match
<NavHashLink
to="/some/path#with-hash-fragment"
activeClassName="selected"
activeStyle={{ color: 'red' }}
// etc...
>Link to Hash Fragment</NavHashLink>
- Smooth scroll to the element
- React Router Hash Link uses the native Element method
element.scrollIntoView()
for scrolling, and when thesmooth
prop is present it will call it with the smooth option,element.scrollIntoView({ behavior: 'smooth' })
- Note that not all browsers have implemented options for
scrollIntoView
- see MDN and Can I Use - there is also a browser polyfill for smooth scrolling which you can install separately sosmooth
will work in all browsers
import { HashLink } from 'react-router-hash-link';
<HashLink smooth to="/path#hash">Link to Hash Fragment</HashLink>
- Custom scroll function called with the element to scroll to, e.g.
const myScrollFn = element => {...}
- This allows you to do things like scroll with offset, use a specific smooth scrolling library, or pass in your own options to
scrollIntoView
import { HashLink } from 'react-router-hash-link';
<HashLink
to="/path#hash"
scroll={el => el.scrollIntoView({ behavior: 'instant', block: 'end' })}
>Link to Hash Fragment</HashLink>
- To scroll to the top of the page set the hash fragment to
#
(empty) or#top
- This is inline with the HTML spec, also see MDN
import { HashLink } from 'react-router-hash-link';
<HashLink to="/path#top">Link to Top of Page</HashLink>
// or
<HashLink to="#top">Link to Top of Page</HashLink>
- To scroll with offset use a custom scroll function, one way of doing this can be found here
- Scroll to the element with matching id
- Used instead of providing a hash fragment as part of the
to
prop, if both are present then theelementId
will override theto
prop's hash fragment - Note that it is generally recommended to use the
to
prop's hash fragment instead of theelementId
The exported components are wrapped versions of the Link
and NavLink
exports of react-router-dom. In some cases you may need to provide a custom Link
implementation.
For example, the gatsby static site generator requires you to use its implementation of Link
. You can wrap it with the genericHashLink
function of this package.
import { genericHashLink } from 'react-router-hash-link';
import GatsbyLink from 'gatsby-link';
const MyHashLink = genericHashLink(GatsbyLink);
const MyComponent = () => (
<div>
The default wont work for you?
<MyHashLink to="/faq#how-to-use-custom-link">No problem!</MyHashLink>
</div>
);