@k8ordo/router

サブパスの下で配信する

アプリをオリジンの直下ではなく、https://example.com/docs/のようなサブパスの下で配信することがあります。そのときもルート表はアプリの根から書いたままにして、サブパスの付け外しはルーターに任せます。

このページの内容

Viteのbaseを設定する

サブパスはViteのbaseで指定します。ルーターはimport.meta.env.BASE_URLからその値を読みます。

vite.config.ts
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';

export default defineConfig({
  base: '/docs/',
  plugins: [react()],
});

ルート表は書き換えません。/productsのページは、表の中では/productsのままで、ブラウザのアドレスバーでは/docs/productsになります。

hrefとnavigateToは、作ったURLの前にサブパスを付けます。

ts
href('/products'); // '/docs/products'
href('/'); // '/docs/'

hrefの戻り値の型が、表のパスではなくstringになっているのはこのためです。返すのは、サブパスの付いたURLです。

情報

メモ

@k8ordo/staticや@k8ordo/serverの下でも同じです。Server Actionのredirect()に渡すURLも、hrefで作るとサブパスが付きます。

警告

落とし穴

hrefが返したURLを、@k8ordo/stateのhrefに渡さないでください。@k8ordo/stateのhrefもサブパスを付けるので、/docs/docs/productsのように2重になります。渡すのは、/productsのような表のパスです。

読み取るパスからはサブパスが外れる

usePathnameは、サブパスを外したパスを返します。/docs/productsを開いているとき、値は/productsです。

そのため、返ってきたパスはルート表のパターンとそのまま比べられます。useMatchもサブパスを外したパスで判定し、<Router>もサブパスより下のパスで表を照合します。

サブパスの外のURLはアプリのものではないので、ルート表に何が書いてあっても、<Router>は引き受けずにブラウザに任せます。

自分のコードで付け外しする

withBaseとwithoutBaseは、ルーターが行う付け外しを自分のコードで使うための関数です。

ts
withBase('/products'); // '/docs/products'
withoutBase('/docs/products'); // '/products'
withoutBase('/docs'); // '/'
withoutBase('/elsewhere'); // null

withoutBaseは、サブパスの外のパスにnullを返します。サブパスそのもの(/docs)は、末尾のスラッシュが無くても/になります。

Viteを通らないコードにはimport.meta.envが無いので、2つ目の引数でサブパスを渡します。

ts
withBase('/products', '/docs/'); // '/docs/products'

./のような相対のbaseはパスを指していないので、どちらの関数も何も付け外ししません。

k8ordo

Baselineに入った機能を、制限なく使うReactのライブラリ群。

© 2026 k8o — MIT License

組版:Noto Sans JP / M PLUS 2