ホームページ > ウェブフロントエンド > CSSチュートリアル > Next.js のサーバー コンポーネントでアクティブな Nav リンクのスタイルを設定する方法

Next.js のサーバー コンポーネントでアクティブな Nav リンクのスタイルを設定する方法

Patricia Arquette
リリース: 2024-11-26 20:04:14
オリジナル
498 人が閲覧しました

皆さん、こんにちは! 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;
ログイン後にコピー

ブラウザでは次のように表示されます:

How to style active Nav links in server components in Next.js


ただし、このアプローチの問題は、コンポーネントがクライアントベースであるため、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 サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート