On websites it’s common to have a navigation header (or sidebar) with links that have an “active” state, which means they get a visual indication that you’re on that specific page.
Let’s see how to do that with Remix.
You know how to use the Link
component to link to another page:
<Link to="/about">
About
</Link>
There’s another Remix component called NavLink
that does the same, but also comes with additional functionality attached.
import { NavLink } from "@remix-run/react"
If Remix knows the link is active, it adds the active
HTML class to it, so you can style it with CSS. When the active link is pending (undefined), it will have a pending
class.
You can provide a callback function to the className
prop to customize the class when the link is active, for example to add a Tailwind class:
<NavLink
to="/about"
className={({ isActive }) =>
isActive ? "font-bold" : ""
}
>
About
</NavLink>
Let’s do an example, suppose you have 3 routes: /
, /about
and /contact
, powered by 3 files:
app/routes/_index.jsx
app/routes/about.jsx
app/routes/contact.jsx
We’ll have a component imported by those 3 route components, let’s call it Nav
.
Create a folder app/components
and a new file Nav.jsx
In there we create links to those 3 routes using NavLink
:
import { NavLink } from '@remix-run/react'
export default function Nav() {
return (
<nav className='flex gap-4'>
<NavLink
to='/'
className={({ isActive }) => (isActive ? 'font-bold' : '')}>
Home
</NavLink>
<NavLink
to='/about'
className={({ isActive }) => (isActive ? 'font-bold' : '')}>
About
</NavLink>
<NavLink
to='/contact'
className={({ isActive }) => (isActive ? 'font-bold' : '')}>
Contact
</NavLink>
</nav>
)
}
Now you can import this component on top of every route component, like this:
//app/routes/contact.jsx
import Nav from '../components/Nav'
export const meta = () => {
return [{ title: 'Contact' }]
}
export default function Contact() {
return (
<div style={{ fontFamily: 'system-ui, sans-serif', lineHeight: '1.4' }}>
<Nav />
<h1>Contact us</h1>
<p>Contact form: ...</p>
</div>
)
}
//app/routes/about.jsx
import Nav from '../components/Nav'
export const meta = () => {
return [{ title: 'About page' }]
}
export default function About() {
return (
<div style={{ fontFamily: 'system-ui, sans-serif', lineHeight: '1.4' }}>
<Nav />
<h1>About this site</h1>
<p>It's a very cool site!</p>
</div>
)
}
And if you open the site in the browser you’ll see the navigation apply the font-bold
Tailwind CSS class if the route corresponds to the NavLink
: