結論
VueRouterを使用して、サブディレクトリへのアクセスをもとにルーティングを行いたいときはトップディレクトリを参照するようにサーバー側の設定が必要。
例
下記のように、www.website.com/app にアクセスした際にはAppHomeを、www.website.com/app/aboutにアクセスした際にはAboutコンポーネントを表示させたいとする。
AppHomeの表示に関しては、特に気にすることなく、サーバー側の公開ディレクトリにビルド後のファイルを配置すれば正常に表示される。
一方で、Aboutの表示は、そのままでは404NotFoundなどの結果が返ってくる。
main.ts
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: AppHome,
},
{
// サブディレクトリへのアクセスを制御したい
path: '/about',
name: 'about',
component: About
},
{
path: '/:catchAll(.*)',
component: ERR404
}
...
理由・解決法
- サブディレクトリ www.website.com/app/about に対するリクエストを受けたWEBサーバーは/app/about/index.htmlを探しに行くが、そのようなディレクトリ・ファイルは存在せず、404エラーを返すため。
- VueRouterに処理をさせるには、リクエストをVueRouterまで届けないといけない
- 具体的には、Vueの場合は、/app/about へのアクセスを、/app に対してリダイレクトさせる必要がある
解決法具体例 Nginxの場合
wwww.website.com/app/* に対してアクセスがあった際に該当ファイルがなければ、/appへリダイレクトされ、/app配下のvueアプリケーションまでリクエストが届けられ、VueRouterで処理がなされる。
nginx.conf
#For Vue-Router
location /app {
files $uri $uri/ /app;
}
余談と経緯
- VueRouterを使用して上記のようなことをした際に、ローカルの開発環境では問題ないが、ビルドしてサーバーに上げるとサブディレクトリへのアクセス404になるという現象に遭遇し時間をとられた。
- VueRouterというくらいだから、サーバーへのアクセスよしなにやってくれるんだ楽ちんくらいの気持ちでおり、WEBサーバーとVueとのやり取りの仕組みをよく理解せず使っていたため、解決に時間がかかった。
- nginx の confファイルが複数あり、書いても書いても反映されずにそこでも時間をくった