5 min read
How to use useSelectedLayoutSegment in Next.js App Router
Bharat Kilaru
Understanding the useSelectedLayoutSegment Hook in Next.js
We're exploring the useSelectedLayoutSegment
hook from Next.js's navigation package. Let's say you're writing a layout component, but want to access route segments in the client outside the scope of the layout. Let's run through a specific example where there's a layout with active link segments highlighted. You won't know the active link based on the layout component since you can't access the route segments. That's where the useSelectedLayoutSegment
hook comes in handy!
Importing useSelectedLayoutSegment
To begin with, we need to import the useSelectedLayoutSegment
hook from the next/navigation
package. This is done as follows:
import { useSelectedLayoutSegment } from "next/navigation";
Calling useSelectedLayoutSegment
Next, we need to call useSelectedLayoutSegment
and assign it to a variable. This hook returns the currently selected layout segment.
const selectedSegment = useSelectedLayoutSegment();
Understanding the Functionality
The useSelectedLayoutSegment
hook provides us with the currently selected layout segment. This can be used to determine which navigation link is currently active. As the user switches between potential tabs, the route segment and then the selectedSegment
will change accordingly.
Creating an Active Link Component
We can use the useSelectedLayoutSegment
hook to create a component that represents an active link. This component will have a different style when it is active.
const isActive = slug === segment
<Link
href={`/blog/${slug}`}
// Change style depending on whether the link is active
style={{ fontWeight: isActive ? 'bold' : 'normal' }}
>
{children}
</Link>
Checking if a Link is Active
In the above example, we used the selectedSegment
to check if a link is active. If the selectedSegment
equals the href
of the link, the link is active.
Returning a Link Component with Dynamic Style
The ActiveLink
component returns a Link
component from Next.js. The style of the link is dynamic based on whether the link is active or not.
'use client'
import Link from 'next/link'
import { useSelectedLayoutSegment } from 'next/navigation'
// This *client* component will be imported into a blog layout
export default function BlogNavLink({
slug,
children,
}: {
slug: string
children: React.ReactNode
}) {
// Navigating to `/blog/hello-world` will return 'hello-world'
// for the selected layout segment
const segment = useSelectedLayoutSegment()
const isActive = slug === segment
return (
<Link
href={`/blog/${slug}`}
// Change style depending on whether the link is active
style={{ fontWeight: isActive ? 'bold' : 'normal' }}
>
{children}
</Link>
)
}
Importing the Client Component into a Parent Layout
After creating the ActiveLink
component, we can import it into a parent layout component and use it to render navigation links.
import { BlogNavLink } from "./blog-nav-link";
import getFeaturedPosts from "./get-featured-posts";
export default async function Layout({
children,
}: {
children: React.ReactNode,
}) {
const featuredPosts = await getFeaturedPosts();
return (
<div>
{featuredPosts.map((post) => (
<div key={post.id}>
<BlogNavLink slug={post.slug}>{post.title}</BlogNavLink>
</div>
))}
<div>{children}</div>
</div>
);
}
Conclusion
We explored the useSelectedLayoutSegment
hook from Next.js's navigation package! Next time you need to build a tab-based filtering feature or a way to toggle across channels on a page, you can maintain a component in your layout without losing the ability to access the route segments in the client.
Neorepo is a production-ready SaaS boilerplate
Skip the tedious parts of building auth, org management, payments, and emails
See the demo© 2023 Roadtrip