Vue3×ViteでのSSRをサクッと試してみた
Vue3 と Vite(ヴィート)を使って SSR(サーバサイドレンダリング)を試してみた。 Vite は Vue や React のビルドツールだが、その機能を使って SSR が実現できるとのこと。
※現在 Experimental な機能となっているため、本番運用では使わないようにしたほうが良い。破壊的変更があるかもしれないので。
Vue3 プロジェクトの作成
とりあえずまずは Vue3 のプロジェクトを作成する
yarn create vite --template vue-ts
プロジェクト名を適当に vue-ssr-app とかにする

yarn install しておく
cd vue-ssr-app
yarn install
試しに起動
yarn dev
localhost:3000 にアクセスし、developer tool で Doc を確認すると、Response に App.vue の内容が記載されていないとが分かる。 つまり、SPA モードで起動しており、JS によってレンダリングが実行されている。

起動することは確認できたので、以下より SSR を行っていく
SSR 化
以下の step で SSR 化を行う
- ssr に必要なプラグインのインストール
- SSR プラグインの読み込み
- ページ用コンポーネントの作成
- App.vue の修正
- router の作成
- main.ts の修正
- ssr モードで起動
ssr に必要なプラグインのインストール
SSR 化するために必要なプラグインをインストールする
yarn add vite-ssr vue-router@4 @vueuse/head
@vueuse/head は title 等の head 内の属性を設定するためのもの、これを使うと簡単に meta 情報が設定できる
SSR プラグインの読み込み
SSR プラグインの読み込み
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import SSR from 'vite-ssr/plugin'
export default defineConfig({
plugins: [vue(), SSR()]
})
ページ用コンポーネントの作成
top ページに配置するページコンポーネントを作成
nuxt のように pages というディレクトリを作ってみた
src/pages/Root.vue
<script lang="ts" setup>
import { useHead } from '@vueuse/head';
useHead({
title: 'Vite SSR Title'
});
</script>
<template>
Hello Vite SSR!
</template>
シンプルに文字だけを表示するとする。 useHead でタイトル属性の付加した
App.vue の修正
この後 vue router で設定する内容を App.vue 内に流し込むコードを記述するだけ
src/App.vue
<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue'
</script>
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
<RouterView v-slot="{ Component }">
<Suspense>
<component :is="Component" />
</Suspense>
</RouterView>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
router の作成
router を作成する。/にアクセスしたとき Root.vue が呼ばれるようなシンプルなルート
src/router.ts
import { RouteRecordRaw } from 'vue-router';
export const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'ROOT',
component: () => import('/src/pages/Root.vue')
},
];
main.ts の修正
src/main.ts
head 属性をロードしたり、SSR の設定を行ったりする
import { createHead } from '@vueuse/head';
import { viteSSR } from 'vite-ssr/vue';
import { routes } from '/src/router';
import App from '/src/App.vue';
const Options: Parameters<typeof viteSSR>['1'] = {
routes,
pageProps: {
passToPage: false
},
};
export default viteSSR(App, Options, async (params) => {
const { app, initialState, isClient, router } = params;
const head = createHead();
app.use(head);
return {
head
};
});
ssr モードで起動
最後に package.json の dev コマンドを以下のように修正
"dev": "vite-ssr",
これで起動してみると、
yarn dev

Response に Root.vue で記述した「Hello Vite SSR!」があるので、SSR 化されていることが分かる
nuxt や next を使うともっと楽に SSR 化することはできるが、Vue3 のみで作ってきた SPA のアプリケーションを SSR 化したいときは、このような方法を試すと良いかもしれない。ただ実験的機能なので本番導入は見送り。
vite の ssr の issue も頻繁に上がっているっぽい。
https://github.com/vitejs/vite/issues?q=is%3Aissue+is%3Aopen+ssr+