サブパスの下で配信する
アプリをオリジンの直下ではなく、https://example.com/docs/のようなサブパスの下で配信することがあります。そのときもルート表はアプリの根から書いたままにして、サブパスの付け外しはルーターに任せます。
このページの内容
Viteのbaseを設定する
サブパスはViteのbaseで指定します。ルーターはimport.meta.env.BASE_URLからその値を読みます。
vite.config.tsimport react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
export default defineConfig({
base: '/docs/',
plugins: [react()],
});ルート表は書き換えません。/productsのページは、表の中では/productsのままで、ブラウザのアドレスバーでは/docs/productsになります。
リンクにはサブパスが付く
hrefとnavigateToは、作ったURLの前にサブパスを付けます。
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は、ルーターが行う付け外しを自分のコードで使うための関数です。
withBase('/products'); // '/docs/products'
withoutBase('/docs/products'); // '/products'
withoutBase('/docs'); // '/'
withoutBase('/elsewhere'); // nullwithoutBaseは、サブパスの外のパスにnullを返します。サブパスそのもの(/docs)は、末尾のスラッシュが無くても/になります。
Viteを通らないコードにはimport.meta.envが無いので、2つ目の引数でサブパスを渡します。
withBase('/products', '/docs/'); // '/docs/products'./のような相対のbaseはパスを指していないので、どちらの関数も何も付け外ししません。