Nuxt.js + LaravelでSSRチュートリアル (herokuデプロイまで)

どうも、**Webサービス開発大好きヒューマンしがしぃ**と申します😇

今回はWebサービス開発で使用した、**Nuxt.jsとLaravelを用いてサーバーサイドレンダリング**のチュートリアルを解説します！
> [サーバーサイドレンダリングとは](https://ssr.vuejs.org/ja/#%E3%82%B5%E3%83%BC%E3%83%90%E3%82%B5%E3%82%A4%E3%83%89%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0-ssr-%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%8B)

最後にはherokuにデプロイするところまで解説します。
このチュートリアル見て、Nuxt.jsとLaravelの人口が更に増えたら嬉しいな。

# 事前知識
* Laravelについて基礎知識  
Laravelについて分からない方はこちらの学習ロードマップがオススメです⭐️
> [Laravelを学ぶための学習ロードマップ PHP](https://michiakr.com/article/93daf1f2-cf16-459e-ae82-2e24e031f5f4)

* Nuxt.jsについての基礎知識  
Nuxt.jsについて分からない方はこちらの学習ロードマップがオススメです⭐️
> [私がVue.jsのフレームワークであるNuxt.jsを使うまでの道のり](https://michiakr.com/article/df68d61c-8742-4286-bccf-92846c30f0e4)

# 概要
* NuxtとLaravelはサーバーを分けるため、別リポジトリで作り、別サーバーにデプロイ
* Nuxtはフロント、LaravelはAPIサーバーとしてバックエンドを担当する
* axiosを用いてHello Worldと表示するところまで

# Laravelプロジェクト作る
LaravelはAPIサーバとして使用します。

各自の環境でLaravelプロジェクトを作ります。
（私はLaradockを使用しました）

```
$ composer create-project --prefer-dist Laravel-base-API
```

Laravel-base-APIはお好きな名前に変更して下さい。

次にサーバーを起動するコマンドを実行します。

```
$ php artisan serve
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278160/011e6222-5ca4-ceb4-08cb-dc7bcd750671.png)

(私の環境のURLですが)
http://localhost/
この画面が見えます。

続いてHello Worldを追加します。

```routes/api.php
Route::get('/', function () { return 'Hello World'; });
```
を追加します。

# Nuxtプロジェクトを作る
お好きなリポジトリで

```
$ npx create-nuxt-app {Nuxt-base-Front}
> Generating Nuxt.js project in /{hogehoge}
? Project name Nuxt-base-Front
? Project description My flawless Nuxt.js project
? Use a custom server framework none
? Use a custom UI framework none
? Choose rendering mode Universal
? Use axios module yes
? Use eslint yes
? Use prettier no
? Author name {hogehoge}
? Choose a package manager npm
```

{ }の中は{}を外してお好きに設定して下さい。

`? Use axios module yes`
`? Choose rendering mode Universal`
axiosを使うのでyesにすることと、SSRモードにしたいのでUniversalを選択することに注意して下さい。

プロジェクトが完成したら

```
$ npm run dev
```

http://localhost:3000/
にアクセスすると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278160/b2700f7e-28ea-1348-5165-28d2cd15dda8.png)


こんな画面が見えるかと思います。

続いて、新しくファイルを作って以下のように記述します。

```pages/hello.vue
<template>
  <div>
    {{ data }}
  </div>
</template>


<script>
  export default {
    async asyncData ({ app }) {
      const data = await app.$axios.$get(`http://localhost/api`)
      return { data }
    }
  }
</script>
```

フルパスで書くのは良い設計ではないと思うので、変えたい方はproxy module https://github.com/nuxt-community/proxy-module を使ったほうが良いと思います。

`http://localhost:3000/hello`
にアクセスするとhello worldが返ってきます。
**※Laravelのサーバーは立てて下さい。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278160/35c33823-cabe-4c46-12e8-3337f5ea1610.png)


# herokuにデプロイする
初めの頃はNuxt.jsとLaravelを同一リポジトリ開発して、そのままheorkuデプロイしようと思いましたが、難しくて出来ませんでした。
(herokuはポートの関係で1つのコンテナ内に２つ以上アプリケーションを起動できない??)
そのため、分けたほうが早いのでは？と考え、リポジトリを分けてデプロイしました。

## Nuxtデプロイ

Nuxtデプロイはこちらを参考にして下さい。
[Nuxt + Herokuで簡単にデプロイする](https://qiita.com/watkazuki/items/de3e6b50f84fcc188fa5)

```
$ heroku login
```

herokuログイン後、

```
$ heroku git:remote -a nuxt-base-front
```
(remote先の値は変更して下さい)

```
$ heroku config:set NPM_CONFIG_PRODUCTION=false
$ heroku config:set HOST=0.0.0.0
$ heroku config:set NODE_ENV=production
```
環境変数を設定し、

```package.json
"heroku-postbuild": "npm run build”
```

package.jsonのscriptsに追加します。

その後、herokuにpushします。

```
$ git add .
$ git commit -am "make it better"
$ git push heroku master
```

https://nuxt-base-front.herokuapp.com/
にアクセスするとトップページが見れると思います。
(nuxt-base-frontは自分のアプリ名に変えてください)

## Laravel deploy

Laravelデプロイはこのサイトを参考にして下さい
[Laravel5.7: Herokuにデプロイする](https://qiita.com/sutara79/items/a173b969474d9f5afe1b)

LaravelプロジェクトにProcfileを作ります。

```
web: vendor/bin/heroku-php-apache2 public/
```

既にログイン出来ていると思うので、

```
$ heroku git:remote -a laravel-base-api
```

```
$ git add .
$ git commit -am "make it better"
$ git push heroku master
```

```
$ heroku config:set APP_KEY=$(php artisan --no-ansi key:generate --show)
```
これは忘れないで下さい。APP_KEYを設定しなければ、Laravelは動きません！

https://laravel-base-api.herokuapp.com/
にアクセスするとトップページが見れると思います。
(laravel-base-apiは自分のアプリ名に変えて下さい)

#Oops!
Nuxtのaxiosで問い合わせた先がローカルのままだと、エラーが発生します!!
問い合わせ先をLaravelのURL変えましょう!!

```pages/hello.vue
<template>
  <div>
    {{ data }}
  </div>
</template>


<script>
  export default {
    async asyncData ({ app }) {
      const data = await app.$axios.$get(`https://laravel-base-api.herokuapp.com/api/`)
      return { data }
    }
  }
</script>
```

再度アクセスすると、https://nuxt-base-front.herokuapp.com/hello にアクセスすると


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278160/b5e83b27-30b8-7735-750d-bf2ad7c89476.png)


出来ました！

ソースを見てみると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278160/384dcdad-99eb-267b-a97e-a246e23aaaa9.png)



Hellow Worldと見えるので、SSRが成功していることが分かります！

# CORSエラー

（起きるつもりで書いていたが、SSRでブラウザではなく、サーバーから問い合わせているから起きなかったのかな）
起きたらここ参照にして下さい。
https://github.com/barryvdh/laravel-cors

# おわりに

注意点は
所々、自分の環境に当てはめて実行して下さい！（テンプレートやアプリ名、URLなど）

今回のリポジトリ置いておきます！

Nuxt-base-Front: https://github.com/MyPoZi/Nuxt-base-Front
Laravel-base-API: https://github.com/MyPoZi/Laravel-base-API

とりあえずチュートリアルはこんな感じです。ここまで出来れば、あとはコードゴリゴリ書いていけばアプリが出来ると思います！

お疲れ様でした😊