この記事について
Next.jsの router オブジェクトに存在するメソッドの router.push と router.replace が似ていて、どちらを使用するのがベストなのか分からなくなる場面があった為、それぞれの違いと最適な使い道についてNext.jsの実装を参考にしながらまとめました。
router.push
構文
router.push(url, as, options)
できること
指定したリンクにぺージ遷移ができます。
型
router.pushの返り値の型はPromiseで、ジェネリクスで渡している型はbooleanです。
push(url: Url, as?: Url, options?: TransitionOptions): Promise<boolean>;
使用例
import { useRouter } from 'next/router'
export default function Page() {
  const router = useRouter()
  return (
    <button type="button" onClick={() => router.push('/home')}>
      Click me
    </button>
  )
}
向いている使い方
- プロジェクト内でページ遷移したいとき
 - ドキュメントによると外部リンクを指定する場合は、
window.locationを使うと良いとの記述がありました- 
router.pushで外部リンクを指定しても、内部の実装ではwindow.location.hrefで遷移する処置を書いていたので使用しても問題なさそうです(該当コード) 
 - 
 
router.push外部URLに使用する必要はありません。
window.locationは、これらの場合に適しています。
https://nextjs.org/docs/api-reference/next/router
router.replace
構文
router.replace(url, as, options)
できること
指定したリンクにぺージ遷移ができます。
router.pushとの違いは、指定したURLをhistoryのスタックに追加せずに上書きしてページ遷移する点です。
NextはURLのhistoryをwindow.historyで管理していますが、router.replaceは直接historyを上書きする感じで実装されていそうでした(該当コード)
型
router.replaceの返り値の型はPromiseで、ジェネリクスで渡している型はbooleanです。
router.pushの型と同一です。
replace(url: Url, as?: Url, options?: TransitionOptions): Promise<boolean>;
使用例
import { useRouter } from 'next/router'
export default function Page() {
  const router = useRouter()
  return (
    <button type="button" onClick={() => router.replace('/home')}>
      Click me
    </button>
  )
}
向いている使い方
- ユーザに無効なURLにアクセスされた場合に、指定ページにリダイレクトするとき(
/400、/500等) 
向いてる場面の例
仕様:ログインしないと閲覧できないページ(/profile/detail)があり、ログインしていない状態でアクセスされたら/400に遷移させる
pushの場合だとこうなります
「/profile/detail」 にアクセス → 「/400」 にリダイレクト
history: [/profile/detail, 400]
結果
/400 からブラウザバックすると/profile/detailに戻れる
replaceの場合だとこうなります
「/profile/detail」 にアクセス → 「/400」 にリダイレクト
history: [400]
結果
historyが上書きされるので/400 からブラウザバックできない
まとめ
- 基本ページ遷移には
router.pushを使用するで問題ない - アクセス制限したいページがあり、リダイレクト処理を行う場合は
router.replaceが向いている 
おまけ
- 
router.backはwindow.history.backと全く同じ(該当コード) - 
router.reloadはwindow.location.reloadと全く同じ(該当コード) - 
Nextはスクロール位置を
sessionStorageに保存してそう(該当コード) 
localStorage に保存されたデータに期限がないのに対して、sessionStorage に保存されたデータはページのセッションが終了するときに消去されます。
ページのセッションはブラウザを開いている限り、ページの再読み込みや復元を越えて持続します。参考: MDN
不明だった事
- 
router.pushやrouter.replaceなどのメソッドがPromiseを返している理由が不明でした。どなたかご存知の方いたら教えてくださると嬉しいです!!