皆さん、こんにちは! Next.js は現在、特に新しいバージョン 15 で非常に人気があり、多くの優れた機能が追加されました。しかし、今日はそれについてではありません。 Next.js の最もよく知られた機能は、ファイルベースのルーターと組み込みの SSR (サーバーサイド レンダリング) です。
SSR は複雑なトピックであり、特にアプリのサーバーとクライアントの状態の同期に関しては、多くの人が代わりにクライアントサイド レンダリング (CSR) を選択します。もちろん、サーバー コンポーネントが実現できないシナリオもありますが、重要な点は、Next.js はパフォーマンスと SEO を強化するために基本的に SSR を中心に構築されており、サーバー上でのレンダリングの恩恵を受けるアプリケーションにとって強力な選択肢となっているということです。
そうそう、特定のページにいるときにリンクが強調表示されるナビゲーションバーを作成するにはどうすればよいでしょうか?基本的なアプローチは、リンクの配列を反復処理し、ブラウザ内の現在のパスとパス名が一致するリンクを強調表示することです。 Next.js でパス名を取得するには、Pathname (ページ ルーターの useRouter) フックを使用します。このアプローチでは、次のような結果になります:
"use client"; import { cn } from "@/lib/utils"; import { usePathname } from "next/navigation"; import Link, { type LinkProps } from "next/link"; type ClientNavProps = { links: LinkProps[]; }; function ClientNav({ links }: ClientNavProps) { const pathname = usePathname(); const isActive = (href: LinkProps["href"]) => { const hrefStr = href.toString(); if (hrefStr === pathname) return true; if (hrefStr.length > 1 && pathname.startsWith(hrefStr)) return true; return false; }; return ( <nav className="space-x-2"> {links.map((e) => ( <Link {...e} key={e.href.toString()} className={cn( "px-2 py-1 border rounded-lg", isActive(e.href) && "bg-black text-white" )} /> ))} </nav> ); } export default ClientNav;
ブラウザでは次のように表示されます:
ただし、このアプローチの問題は、コンポーネントがクライアントベースであるため、SEO には理想的ではないことです。サーバー コンポーネントでクライアント フックを呼び出すことはできないため、サーバー側でパス名を取得して現在のリンクを強調表示する方法という問題に対処する必要があります。
この質問に答えるのは難しくありません。ここではミドルウェアが役に立ちます。ミドルウェアを使用すると、パス名を応答ヘッダーに追加し、すべてのページ ルートに対してトリガーされるように設定できます。
import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; export const config = { matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"], }; export default function middleware(request: NextRequest) { const requestHeaders = new Headers(request.headers); requestHeaders.set("x-next-pathname", request.nextUrl.pathname); return NextResponse.next({ request: { headers: requestHeaders } }); }
現在のパス名を持つ x-next-pathname ができたので、headers 関数を使用してアクセスできます (Next 15 以降では、header、cookie、params、searchParams が非同期になっていることに注意してください)。
import { cn } from "@/lib/utils"; import { headers } from "next/headers"; import Link, { type LinkProps } from "next/link"; type ClientNavProps = { links: LinkProps[]; }; async function ServerNav({ links }: ClientNavProps) { const headersList = await headers(); const pathname = headersList.get("x-next-pathname") || "/"; const isActive = (href: LinkProps["href"]) => { const hrefStr = href.toString(); if (hrefStr === pathname) return true; if (hrefStr.length > 1 && pathname.startsWith(hrefStr)) return true; return false; }; return ( <nav className="space-x-2"> {links.map((e) => ( <Link {...e} key={e.href.toString()} className={cn( "px-2 py-1 border rounded-lg", isActive(e.href) && "bg-black text-white" )} /> ))} </nav> ); } export default ServerNav;
アプリ内でサーバー ナビゲーションバーを配置する場所には注意してください。この特定の例は、URL の変更時に再レンダリングする必要があるため、page.tsx ファイル内で使用された場合にのみ機能します。
これは、現在アクティブなリンクを強調表示するサーバー側のナビゲーションバー コンポーネントを構築する最も簡単な方法と思われます。以上です。読んでいただきありがとうございました。また次回お会いしましょう!
以上がNext.js のサーバー コンポーネントでアクティブな Nav リンクのスタイルを設定する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。