blog-hero-img

React RouterやTanStackを使わないページ移動の実装方法(File-based routing)

pen-icon2026.3.10

この記事は約2分で読めます

Next.jsのような『ファイルがそのままページに対応する仕組み』を、パッケージに頼らず実装してみましょう。

意外とシンプルに実現できます。

Profile Pic

筆者:三好アキ

▶︎ 三好アキの著書一覧はこちら

パッケージなしでページを遷移(ファイルでページを設定)

React(+ Vite)アプリでページ切り替え(ルーティング)を実装する時には、React RouterやTanStack Routerを使うのが一般的です。

しかしこれらを使わずともルーティングは可能なので、その簡単な方法を紹介します。

本記事では、Next.jsのような『ファイルがページに対応している切り替え(File-based routing)』を説明します。

コードでページを切り替える方式(Code-based routing)については、こちらの記事をご覧ください。

まずはReact + Viteを用意しましょう。

そしてindex.css内のコードはすべて消しておいてください。

(*React + Viteのセットアップについてはこちらの記事をご覧ください)

ページの用意

ページとして使うファイルを入れるpagesフォルダを用意します。

page-based-routing-1

次のようにファイルを用意してください。

page-based-routing-2

各ファイルには次のように書きます。

// pages/home.jsx

const Home = () => {
    return (
        <div>
            <h1>Home</h1>
        </div>
    )
}

export default Home
// pages/about.jsx

const About = () => {
    return (
        <div>
            <h1>About</h1>
        </div>
    )
}

export default About
// pages/notfound.jsx

const NotFound = () => {
    return (
        <div>
            <h1>Not Found</h1>
        </div>
    )
}

export default NotFound

ページ切り替えの仕組みの用意

まずApp.jsxのコードをすべて消して、次のように書いてください。

// App.jsx

const App = () => {
    return 
}

export default App

そして先ほど作ったファイルをすべて読み込みます。

// App.jsx

const pages = import.meta.glob("./pages/**/*.jsx", { eager: true })   // 追加

const App = () => {
    return 
}

export default App

参考ですが、このpagesの中身は次のようになっています。

page-based-routing-3

次はファイルパスをURLに変換します。

// App.jsx

const pages = import.meta.glob("./pages/**/*.jsx", { eager: true })

// ⬇追加
function normalizePath(filePath) {
    return filePath
        .replace("./pages", "")
        .replace("/home.jsx", "")
        .replace(".jsx", "") || "/"
}
// ⬆追加

const App = () => {
    return 
}

export default App

最後に、これらを使ってルーティングを実現するコードを追加しましょう。

// App.jsx

import { useEffect, useState } from "react"         // 追加

const pages = import.meta.glob("./pages/**/*.jsx", { eager: true })

function normalizePath(filePath) {
    return filePath
        .replace("./pages", "")
        .replace("/home.jsx", "")
        .replace(".jsx", "") || "/"
}

const App = () => {
    // ⬇追加
    const [path, setPath] = useState(window.location.pathname)

    useEffect(() => {
        const onPopState = () => setPath(window.location.pathname)
        window.addEventListener("popstate", onPopState)
        return () => window.removeEventListener("popstate", onPopState)
    }, [])

    const Page = Object.entries(pages).find(
        ([file]) => normalizePath(file) === path
    )?.[1].default

    return Page ? <Page/> : <h1>エラー</h1>
    // ⬆追加
}

export default App

Linkタグの用意

ページを移動するリンクに<a>タグを使い、次のように書くとします。

<a href="/about">About</a>

しかしこれではページがリロードされてしまい、SPA(Single Page Application)の特徴である「スムーズなページ遷移」にはなりません。

なので専用の<Link>タグを用意しましょう。

Link.jsxを作ってください。

page-based-routing-4

次のように書きます。

// Link.jsx

export function Link({ to, children }) {
    const handleClick = (e) => {
    e.preventDefault()
    window.history.pushState({}, "", to)
    window.dispatchEvent(new PopStateEvent("popstate"))
}

return (
        <a href={to} onClick={handleClick}>
            {children}
        </a>
    )
}

export default Link

そして各ページに読み込みましょう。

// pages/home.jsx
import Link from "../Link"     // 追加

const Home = () => {
    return (
        <div>
            <h1>Home</h1>
            <Link to="/about">About</Link>     // 追加
        </div>
    )
}

export default Home
// pages/about.jsx
import Link from "../Link"     // 追加

const About = () => {
    return (
        <div>
            <h1>About</h1>
            <Link to="/home">Home</Link>     // 追加
        </div>
    )
}

export default About
// pages/notfound.jsx
import Link from "../Link"     // 追加

const NotFound = () => {
    return (
        <div>
            <h1>Not Found</h1>
            <Link to="/home">Home</Link>     // 追加
        </div>
    )
}

export default NotFound

これで、パッケージを使わない、ファイルベースでのルーティングをReactに実装できました。

しかしこのようなマニュアル方式には限界もあります。

この実装方法の限界

ページが増えたときにコードも増えていく、動的ルートが扱いづらい、テストが書きづらいといった問題が典型的です。

そのためやはり一般的には、React RouterやTanStack Routerといったパッケージを使うことになります。

なお、もうひとつの切り替え方式である『コードでページを切り替える方法(Code-based routing)』については、こちらの記事をご覧ください。


image

▼【無料フロントエンド・ガイド】は下記ページで受け取れます。

https://monotein.com/present-for-readers

Profile Pic

🟩 フロントエンド開発者入門ガイド【無料配布中】


最初にこれが知りたかった!
フロントエンド初心者が必ず押さえておきたい ― 『挫折しない勉強法』とその具体的ステップ、無料配布中。
(*名前不要・メールアドレスだけで受け取り可能です)