💭

ホームページとSPAを同時にホストする方法 | Vue + Vercel

に公開

概要

Vueで作ったSPAは、ブラウザで表示されたときにクライアントでレンダリングされる。だから、curlなどで、ウェブサイトにアクセスすると、<div id="app"></div>のようなつれない応答が返ってくる。これはSEO的によくないので、あるドメインのトップページには静的なHTMLを表示して、サブディレクトリにSPAを配置したくなった。具体的には、https://hogehoge.vercel.appにはhome.htmlという静的なHTMLを表示して、https://hogehoge.vercel.app/appには、Vueで作ったSPAのルートファイル(index.html)を表示するというもの。これの実現には、いくつかの設定が必要であった。

構造

root/
├ public/
│  ├ index.html  # Vue.js のエントリファイル(説明なし)
│  └ home.html   # ホームページ用の静的なHTMLファイル(説明なし)
├ src/
│  └ router/
│     └ index.js # Vue Router の設定ファイル(Vue Router を使ってなければいらない)
├ vue.config.js  # Vue.js の設定ファイル(なければ作る)
└ vercel.json    # Vercel の設定ファイル(なければ作る)

設定

Vue Router の設定(src/router/index.js)

index.js
import { createRouter, createWebHistory } from 'vue-router';
import SomethingView from '@/views/SomethingView.vue';

const routes = [
  {
    path: '/',
    name: 'Something',
    component: SomethingView,
  },
];

const router = createRouter({
  history: createWebHistory('/app/'), // ← '/app/' に変更
  routes,
});

export default router;

Vue Config の設定(vue.config.js)

vue.config.js
const { defineConfig } = require('@vue/cli-service');

module.exports = defineConfig({
  transpileDependencies: true,
  outputDir: 'dist/app',
  publicPath: '/app/',
});

Vercel の設定(vercel.json)

vercel.json
{
  "rewrites": [
    {
      "source": "/",
      "destination": "/app/home.html"
    },
    {
      "source": "/app",
      "destination": "/app/index.html"
    },
    {
      "source": "/app/:path*",
      "destination": "/app/index.html"
    }
  ]
}

Discussion