PractiX Code Lab

【Next.js】middlewareで初回訪問者にだけローディング画面を表示する方法

Share this post

🚪はじめに

こんにちは、管理人のTKGです。

今回はNext.jsのmiddlewareを活用して、「初回訪問者にだけローディングアニメーションを表示する方法」を解説します。

ユーザー体験を向上させるために、サイト初回訪問時にのみ特別なローディング演出を表示したい場面があります。 ただし、訪問するたびに毎回同じ演出を表示すると、かえってUXの妨げになる可能性もあります。 そこで今回は、Cookieとmiddlewareを組み合わせて、「初回訪問時のみ」ローディングを表示する仕組みを実装してみます。


🧠 middlewareとは?

Next.jsのmiddlewareは、リクエストがルーティングされる前のタイミングで実行できる関数です。

例えば、次のような処理を行うのに最適です:

  • ログインしていないユーザーのリダイレクト
  • 地域や言語によるルーティング分岐
  • Botや特定User-Agentのフィルタリング
  • Cookieを使ったアクセス制御

このmiddlewareはEdge Runtimeで実行可能なため、非常に高速に応答できるのも特徴です。

今回はこの仕組みを使って、**「訪問者が初めて来たかどうか」**を判定し、必要であれば/loadingページへリダイレクトする、という流れを作ります。


🎯この記事でわかること

  • middlewareの基本と使いどころ
  • Cookieを使った初回訪問判定の考え方
  • App Router環境でのローディング画面制御
  • Botアクセスやリロード時の挙動への配慮

🧱 前提

  • Next.js(App Router)環境を想定
  • /loading ページを表示してからトップページへ戻す
  • Cookieを使って「訪問済み」フラグを判定

🔧 1. middleware.tsの作成

まずはルート直下にmiddleware.tsを設置します。

// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function middleware(request: NextRequest) {
  const visited = request.cookies.get("visited");
  const userAgent = request.headers.get("user-agent") || "";
  const currentUrl = request.nextUrl;

  const isBot = /Twitterbot|facebookexternalhit|LinkedInBot|Slackbot|Discordbot/i.test(userAgent);

  if (!visited && !isBot && currentUrl.pathname !== "/loading") {
    const redirectUrl = new URL("/loading", request.url);
    redirectUrl.searchParams.set("from", currentUrl.pathname);

    const response = NextResponse.redirect(redirectUrl);
    response.cookies.set("visited", "true", { maxAge: 60 * 60 * 24 });

    return response;
  }

  return NextResponse.next();
}

📦 2. middlewareの適用範囲を設定(next.config.js

// next.config.js
module.exports = {
  matcher: ["/((?!_next|favicon.ico|loading).*)"],
};


💫 3. ローディングページ(/loading)を作成

// app/loading/page.tsx
"use client";

import { useEffect } from "react";
import { useRouter, useSearchParams } from "next/navigation";

export default function LoadingPage() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const from = searchParams.get("from") || "/";

  useEffect(() => {
    const timer = setTimeout(() => {
      router.replace(from);
    }, 2000);

    return () => clearTimeout(timer);
  }, [from]);

  return (
    <div className="flex items-center justify-center h-screen bg-black text-white">
      <p>初回アクセスありがとうございます。読み込み中...</p>
    </div>
  );
}

👀 4. 補足:Bot対策と注意点

  • SNSのOGP取得などでアクセスしてくるBotは、user-agentにより除外しています。
  • /loadingページ自体にリダイレクトしないようにpathname !== "/loading"で制御しています。
  • Cookieの有効期限は「24時間(1日)」としていますが、用途に応じて調整可能です。

📝 まとめ

今回紹介した「初回訪問者のみローディング画面を表示する」仕組みは、以下の3つの技術要素を組み合わせることで実現しています:

要素役割
middlewareリクエスト前に処理を挟み、リダイレクト制御
Cookie「訪問済み」かどうかを判定するフラグとして使用
クライアント側遷移/loading ページから元のページへ戻す(UX配慮)

このような実装は、マーケティング的な導入演出や、ブランディング目的のアニメーション表示にも応用可能です。

必要以上に表示されないよう設計することで、UXを損なわずに印象を高める体験設計ができます。


🚀成果物リンク

👉 Takashi Sekiguchi | Portfolio


✅ おわりに

このように、Next.jsのmiddlewareとCookieを組み合わせることで、「初回訪問者だけ」特定の画面を表示する演出が実現できます。

UXを高めたいファーストビュー演出や、ブランドの印象づけを強めたいときに便利です。ぜひ取り入れてみてください。

Share this post