ブログ構築 5. ブログ記事周りの構築 #03
2020年04月09日に更新

Nuxt.jsのgenerateプロパティに動的なルーティングを追加する

この記事で達成すること

この記事では、Nuxt.jsにgenerateプロパティを追加して、動的なルーティングの静的ファイルを出力する設定を行います。

nuxt.config.js

2019-10-11 14-16-51

は?動的?静的?なんやそれ?と思われた方、心配ありません。順に説明して操作に入ります。

まず、現状を確認しましょう。

現状の問題点の確認

デモブログのトップページに移動して、「この記事をみる」をクリックし記事を表示してみてください。

2019-10-06 07-56-37

どうですか?ちゃんと記事が表示されましたね。

それでは、その記事ページをリロードしてみてください。

2019-10-06 08-08-57

エラーが出ました。「そんなページ無いよ」と怒られました。

これはなぜでしょう。

答えはサーバーにHTMLファイルがないから

答えは簡単です。

指定されたURLを見に行っても、その場所にはHTMLファイルが無いからです。

今の状態が、サーバー側でHTMLファイルを生成出来ていない、いわゆる「サーバーサイドレンダリング」が出来ていない状態です。

トップページを経由した場合に表示できるのは何故?

それでは何故、トップページを経由した場合は記事が表示されるのでしょうか。

それは、クライアント(ブラウザ)でHTMLファイルを生成しているからです。

これが「シングルページアプリケーション」の仕組みです。

あれ?トップページは表示できるけど…

あれ?また疑問が出てきました。

トップページは何度リロードしても表示されますね。

それはHTMLファイルが存在するからです。

トップページは「サーバーサイドレンダリング」が出来ているんですね!

記事ページだけレンダリングが出来ていないのはなんで?

記事ページだけサーバーサイドレンダリングが出来ていないのは、Nuxt.jsの仕組みにあります。

その前にまず、レンダリングの仕組みを説明します。

サーバーサイドレンダリングの仕組み

Nuxt.jsは、generateコマンドが実行された際、ルートごとにHTMLファイルを生成し、distディレクトリに吐き出します。

サーバー側では、そのdistディレクトリを参照し、HTMLファイルを探します。

あ、思い出しましたか?

このチュートリアルを最初からやっている方は勘付くと思いますが、前回Netlifyにこのセッティングをしましたね。

2019-08-11 16-10-06

Netlifyの初期セットアップとNuxtアプリのデプロイを行う

Nuxt.jsは動的なルーティングのレンダリングを無視する

記事ページだけレンダリングが出来ていない理由に戻ります。

上で、ルートごとにHTMLファイルを生成すると説明しましたが、この時にNuxt.jsは動的なルーティングを無視してレンダリングを行います。

動的なルーティングとは、デモブログの記事ページのような、パラメーターごとに表示を切り替えるページのことを言います。

このページは、すべて_slug.vueファイルで表示されています。

理由はわかった。解決策を教えろ

Nuxt.jsがレンダリングを無視するなら自分でセッティングするしかありません。

具体的には、generateコマンド実行時に「このルートのHTMLファイルを生成してね」という設定です。

nuxt.config.jsにgenerateプロパティを追加することで実現します。

nuxt.config.js
export default {
  generate: {
    routes: [
      '/posts/1',
      '/posts/2',
      '/posts/3'
    ]
  }
}

generateプロパティ内のroutes動的なルーティングのパスを配列として渡してあげれば、HTMLファイルを生成してくれます。

ただこれ、毎回追加するの。。。😱

.

.

.

いいえ、大丈夫です。

伝えたかったことは「routesにパスの配列を渡す」ということです。

ここまでのまとめ

作業の入る前に、ここまでの情報を整理します。

  • 現状の問題点

    記事ページをリロードすると「Page Not Found」のエラーがでる

  • 何故か?

    サーバー側にHTMLファイルが無いため

  • Nuxt.jsレンダリングの仕組み

    generateコマンドが実行された時に、ルートごとにHTMLファイルを生成する

  • 何故、記事ページはレンダリングされないのか?

    Nuxt.jsは、動的なルーティングを無視してレンダリングを行うため

  • 解決策

    generateプロパティのroutesに、動的ルーティングのパスを配列で渡す

以上が、ここまでの説明になります。

作業開始!! nuxt.config.jsにgenerateプロパティを追加する

それでは作業に移りましょう。

nuxt.config.jsgenerateプロパティを追加しします。

そしてcontentfulからblogPostを取得して、routersにパスの配列を渡します。

nuxt.config.js
const client = require('./plugins/contentful').default // 追記

export default {

	// 追記
  generate: {
    routes() {
      return Promise.all([
        client.getEntries({
          content_type: process.env.CTF_BLOG_POST_TYPE_ID
        })
      ]).then(([ posts ]) => {
        return [
          ...posts.items.map(post => {
            return { route: `posts/${post.fields.slug}`, payload: post }
          })
        ]
      })
    }
  }

}
  • payload

    mapメソッドでルートの配列を作成する際に、postオブジェクトをpayloadに登録しています。

    ここに登録することで、/posts/_slug.vueからpayloadへとアクセスできます。

    結果、postを再取得する必要が無くなり、ルーティング生成の高速化を実現します。

(参考)/posts/_slug.vueでpayloadを取得する
async asyncData ({ payload }) {
  if (payload) return { currentPost: payload }
}

正しく設定できたか確認してみよう

generateプロパティは、本番環境で実行されるので"http://localhost:3000"で確認することができません。

そこで、yarn generateコマンドを実行して、ターミナルでルーティングが生成されているか確認を行います。

$ yarn generate

...
ℹ Generating pages                                                                                                    ✔ Generated /
✔ Generated posts/sample03
✔ Generated posts/sample04
✔ Generated posts/sample02
✔ Generated posts/sample01
✔ Generated posts/sample05

記事ページのパスが表示されたら成功です。

これで、サーバー側にもHTMLファイルが生成されました。

本番環境でも確認してみよう

ここまでの変更をpushします。

今回は新規作成したファイルが無いので、いつものgit add -Aせずに-amコマンドで一気にコミットします。

$ git commit -am "add_generate_property"
$ git push

Netlityのデプロイログを確認する

Netlityにログインし「Deploys」メニューから最新のデプロイを確認してみましょう。

先ほどのターミナルと同じように表示されていれば成功です。

2019-10-06 10-56-47

デプロイが完了したら、記事ページをリロードしてください。

今度はちゃんと表示されますね。

まとめ

今回は、Nuxt.jsにgenerateプロパティを追加して、サーバー側に各記事ページのHTMLファイルを生成しました。

SNSで記事のURLを貼り付けても表示できるようになりますね。

これが、Nuxt.jsユニバーサルモードの強みでもある「サーバーサイドレンダリング」のメリットです。

さて、次回は?

今回、記事オブジェクトをpayloadに登録したので、contentfulからAPIを取得するロジックを大きく変更します。

middlewareの使い方も説明しますねー。

お楽しみに。

あなたの力になれること
私自身が独学でプログラミングを勉強してきたので、一人で学び続ける苦しみは痛いほど分かります。そこで、当時の私がこんなのあったら良いのにな、と思っていたサービスを立ち上げました。周りに質問できる人がいない、答えの調べ方が分からない、ここを聞きたいだけなのにスクールは高額すぎる...。そんな方に向けた単発・短期間メンターサービスを行っています。下のサービスへお進みください。
独学プログラマのサービス
次の記事はこちら
Udemy
SPA開発
0. 更新情報 #01
ブログ構築カテゴリーの記事修正、更新情報【2020/05/19追記: このカテゴリーの更新を一旦終了といたします】
1. 今回作るアプリケーション #01
Nuxt.jsとContentfulで作るマイブログ
2. 開発環境にNuxt.jsを立ち上げる #01
Nuxt.jsを動かす環境を構築する
2. 開発環境にNuxt.jsを立ち上げる #02
Nuxt.jsのプロジェクトを作成する
2. 開発環境にNuxt.jsを立ち上げる #03
Hello Nuxtを表示する
3. Nuxt.jsアプリを公開する #01
Nuxt.jsをデプロイする前の事前準備を行う
3. Nuxt.jsアプリを公開する #02
Netlifyの初期セットアップとNuxt.jsのデプロイを行う
3. Nuxt.jsアプリを公開する #03
NetlifyにデプロイしたNuxt.jsに独自ドメインを設定する
4. Contentfulのセットアップ #01
【Nuxt.js Universal】Vuetify2.0にバージョンアップしよう
4. Contentfulのセットアップ #02
【画像で説明】Contentfulの使い方。初期設定と各メニューについて学ぶ
4. Contentfulのセットアップ #03
Contentfulにブログ記事モデルを作成していこう
4. Contentfulのセットアップ #04
ContentfulからAPIを取得してNuxt.jsで記事一覧を表示する
5. ブログ記事周りの構築 #01
Nuxt.jsにContentfulのブログ記事を表示する
5. ブログ記事周りの構築 #02
Contentfulから取得した下書き記事を開発環境に表示する
5. ブログ記事周りの構築 #03
Nuxt.jsのgenerateプロパティに動的なルーティングを追加する
5. ブログ記事周りの構築 #04
【Nuxt.js】middlewareを活用しブログ記事取得のパフォーマンスを改善する
6. カテゴリーページの構築 #01
【Contentful】カテゴリーモデルとブログ記事モデルの関連付け
6. カテゴリーページの構築 #02
【Nuxt.js × Contentful】ブログ記事に関連付くカテゴリーを表示する
6. カテゴリーページの構築 #03
【Nuxt.js × Contentful】カテゴリー記事一覧ページを作成する
7. タグ機能の構築 #01
Contentfulにタグモデルを作成し関連付けを行う
7. タグ機能の構築 #02
【Nuxt.js × Contentful】タグに関連付いたブログ記事を表示する
7. タグ機能の構築 #03
Contentfulのincludesを使って関連モデルを取得しタグ一覧ページを作成する
7. タグ機能の構築 #04
Vuetify2のdata-tableの使い方を学んで、タグ一覧ページをレイアウト
9. Nuxt.jsブログカスタマイズ #01
Twitterシェアボタン、フォローボタンの作り方【Nuxt.js Universalモード編】
小ネタ集