はじめに
ページ遷移したときに、前のページのスクロール位置が保持されてしまい最上部から表示されなかったため、それを無効にしたかったのですが、以下の方法を試しても改善されませんでした。
- 画面遷移時にスクロール位置を最上部に移動させるため、
scroll
プロパティをtrue
(または指定なし)にする。 - RootLayoutなどで
<script>
タグを用いて設定。(Next.jsのナビゲーションとブラウザの内部動作との間に複雑な相互作用があり、期待通りにスクロール位置がリセットされないケースが報告されているみたいです。)
環境
- Next.js: 15.1.6
- ブラウザ: Google Chrome
原因
Next.js 13以降のApp Routerでは、SPA的なページ遷移がデフォルトになっています。そのため、ページ遷移時にブラウザのスクロール位置が自動的に保持される仕様になっています。
解決策
方法① scrollRestoration
を設定する
クライアントコンポーネントを作成して、useEffect
とusePathname
を利用することで、遷移後に常にページ最上部へスクロールできます。
具体的な手順
① コンポーネントを作成する
例:
components/ScrollReset.tsx
"use client";
import { useEffect } from "react";
import { usePathname } from "next/navigation";
const ScrollReset = () => {
const pathname = usePathname();
useEffect(() => {
if ("scrollRestoration" in history) {
history.scrollRestoration = "manual";
window.scrollTo(0, 0);
}
}, [pathname]);
return null;
};
export default ScrollReset;
② 作成したコンポーネントをRootLayoutに追加する
例:
app/layout.tsx
import "./globals.css";
import ScrollReset from "@/components/ScrollReset";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="ja">
<body>
<ScrollReset />
<main>{children}</main>
</body>
</html>
);
}
これで全ページでスクロール位置をリセットできます。
方法② 特定のリンクだけに作用させたいとき
URLに #top
をつけることでスクロールをリセットできます。
<Link href="/page#top">リンク</Link>
ブラウザのデフォルト挙動により、ページ最上部へスクロールされます。
ただしURLに #top
が表示されます。