やりたいこと
Vue.jsで個人開発しているSPAアプリケーションにLP(ランディングページ)を埋め込むことがありました。
実現したいこととしては、
- 静的にHTMLを読み込んでほしい(SEO的に、jsなしでも動くことが条件)
- 同じドメイン下に置きたい
- できればVueだけで解决したい(LPのためだけにNuxtやGridsomeで書き直すようなことはしたくない)
調べてみた
最初にたどり着いた方法が、 リバースプロキシ を使ってURLでレスポンスを変える方法でしたが、Vue単体で解決できてないのでとりあえず保留。
色々情報を漁っていると…
Vue.jsには MPA を構築する機能が標準で搭載されているらしい…?
MPAとは
(知っている方は読み飛ばしてください)
VueやReactなど、モダンなフロントエンドフレームでは SPA (シングルページアプリケーション)として開発するのが主流です。つまり、基本的には1つのページで表示をすべて完結させています。
それに対し、 MPA (マルチページアプリケーション)では、従来の方法で各ページでリクエストに対するレスポンスを表示させています。
ざっくりいうと、
- 画面遷移にリロードがあるのがMPA
- 画面遷移にリロードがないのがSPA
といった理解で大丈夫だと思います。
やってみる
VueのMPA機能を使えば、任意のURLに静的なHTMLを配置することができそう、ということがわかりました。
では実際に実装してみましょう。
今更ですが筆者の環境です
- vue-cli v5.0.4
- Vue v3.2.13
- vue-router v4.0.3
- javascript
ディレクトリ構造
root/
└ src/
├ public/
| ├ index.html
| └ landing.html
└ app/ <- src直下にあったメインのアプリケーションを移動させた
| ├ components/..
| ├ App.Vue
| └ main.js
└ landing/ <- LP用のディレクトリ(後述するが、ここに意味のあるコードは置かない)
└ main.js <- 内容は空でよい
おそらく大半の方がsrc
直下にmain.js
やApp.vue
を配置していると思うので、見やすくするためapp
など適当な名前をつけたディレクトリに移動させましょう。(やらなくても可、その場合は適宜以下のパスを読み替えてください)
vue.config.js
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
pages: {
index: {
entry: 'src/app/main.js',
template: 'public/index.html',
},
landing: {
entry: 'src/landing/main.js',
template: 'public/landing.html',
}
}
})
(参考: https://cli.vuejs.org/config/#pages )
defineConfig
にpages
プロパティを追加することでMPAの実装ができるようになります。
ここで必須のプロパティは、entry
のみであり、他のプロパティはオプションです。
今回はHTMLを表示させるのが目的のため、template
を指定します。
また、形式的に追加する必要があるものの、実際は動作させないためpublic/main.js
は空ファイルで大丈夫です。
あとはpublic/landing.html
にHTMLを書いて完成です。
実行した後、http://localhost:8080/landing
にアクセスするとランディングページが表示されるはずです。
おわりに
わりと裏技的な実装な気がしてるので、もう少しよい方法があれば教えてほしいです