🚗

Next.jsでページ遷移時のインジケーターを表示する

に公開

Next.js v15.3.0から提供されたNavigation Hooksの一つ useLinkStatus を使うと簡単にページ遷移時のインジケーターを実装することができます。GIFアニメーションなので、じゃっかん分かりにくいですが、ページ遷移すると上部に青い線が左から右にアニメーションしていく様子が確認できます。こういったインジケーターがシュッと実装できます。

useLinkStatusの使い方

useFormStatus と同じような使い方で、<Link> コンポーネントの子要素として別コンポーネントに切り出して使います。以下のコードは公式ドキュメントからのサンプルコードです。シンプルなので使い方はイメージできると思います。

useLinkStatus は上位の <Link> コンポーネントの状態を自動で取得してくれます。

LoadingIndicator.tsx
'use client'
 
import { useLinkStatus } from 'next/link'
 
export default function LoadingIndicator() {
  const { pending } = useLinkStatus()
  return pending ? <span></span> : null
}
Header.tsx
import Link from 'next/link'
import LoadingIndicator from './LoadingIndicator'
 
export default function Header() {
  return (
    <header>
      <Link href="/dashboard">
        Dashboard <LoadingIndicator />
      </Link>
    </header>
  )
}

標準でインジケータ対応させる

毎回インジケータコンポーネントを呼び出すのは面倒くさいので next/link をラップした <Link> コンポーネントを用意して、デフォルトでインジケータ対応させます。

Link.tsx
import NextLink, { type LinkProps as NextLinkProps } from "next/link";
import { Indicator } from "@/app/Indicator";

interface LinkProps extends NextLinkProps {
  children: React.ReactNode;
  className?: string;
}
export function Link({ children, ...props }: LinkProps) {
  return (
    <NextLink {...props}>
      {children}
      <Indicator />
    </NextLink>
  );
}

アニメーションさせるIndicatorを用意します。今回は冒頭のアニメーションGIFのように画面上部に左から右にバーをアニメーションさせるものを参考実装とします。

Indicator.tsx
"use client";

import { useLinkStatus } from "next/link";

export function Indicator() {
  const { pending } = useLinkStatus();
  return pending ? (
    <span className="fixed top-0 left-0 z-1 h-[3px]
                     bg-blue-300 opacity-50 indicator" />
  ) : null;
}

今回はTailwind CSS v4を使っているので、アニメーション定義を globals.css に書きます。

globals.css
@keyframes indicator-bar {
  0% {
    width: 0;
  }
  50% {
    width: 90%;
  }
  100% {
    width: 100%;
  }
}

@layer utilities {
  .indicator {
    animation: indicator-bar 800ms ease-in-out forwards;
  }
}

これで完成です。簡単にできて嬉しいですね!これで、表示が重いページの遷移もフィードバックがあってユーザも嬉しいでしょう。

ムーザルちゃんねる

Discussion