Making the Most of useSelectedLayoutSegment
Published: 2023-08-05 10:03:55

The web is all about navigation, and as developers, we often need to keep track of where a user is in our app. Navigational elements often change based on where the user is currently at. In Next.js, a popular React framework, this can be accomplished by using the `useSelectedLayoutSegment` hook. This client component hook lets you read the active route segment one level below the layout it is called from, making it an invaluable tool for navigation UI.

## Understanding useSelectedLayoutSegment

In the following example, the `useSelectedLayoutSegment` hook is called from a client component and returns the active segment. 

```TypeScript
'use client'
 
import { useSelectedLayoutSegment } from 'next/navigation'
 
export default function ExampleClientComponent() {
  const segment = useSelectedLayoutSegment()
 
  return <p>Active segment: {segment}</p>
}
```

Given that useSelectedLayoutSegment is a Client Component hook and Layouts are Server Components by default, useSelectedLayoutSegment is typically invoked via a Client Component that is imported into a Layout. The hook returns the segment one level down, making it particularly useful for UI elements such as tabs inside a parent layout, which often need to change their style based on the active child segment. 

If you need to return all active segments, consider using `useSelectedLayoutSegments` instead. 

## Hook Parameters and Returns

`useSelectedLayoutSegment` does not take any parameters. It does, however, return a string of the active segment or null if one doesn't exist. Here are a few examples:

| Layout                   | Visited URL                        | Returned Segment |
|--------------------------|------------------------------------|------------------|
| app/layout.js            | /                                  | null             |
| app/layout.js            | /dashboard                         | 'dashboard'      |
| app/dashboard/layout.js  | /dashboard                         | null             |
| app/dashboard/layout.js  | /dashboard/settings                | 'settings'       |
| app/dashboard/layout.js  | /dashboard/analytics               | 'analytics'      |
| app/dashboard/layout.js  | /dashboard/analytics/monthly       | 'analytics'      |

## Practical Example: Active Link Component

The real power of `useSelectedLayoutSegment` comes into play when we use it to create an active link component that changes its style based on the active segment. Here's an example of how to do this, using a featured posts list in the sidebar of a blog:

```TypeScript
'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>
  )
}
```

And the parent Layout component:

```TypeScript
// Import the Client Component into a parent Layout (Server Component)
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>
  )
}
```

In this example, the `BlogNavLink` component uses `useSelectedLayoutSegment` to determine the active segment. Depending on whether the link is active, the link's style will change, providing a clear visual cue for the user. 

In conclusion, Next.js's `useSelectedLayoutSegment` is a handy hook that can help you build dynamic, user-friendly navigation interfaces. By using it wisely, you can greatly enhance the user experience on your site.