1
/
5

【開発日誌#24】Nuxt.js + WP REST API でブログサイトを制作して、Netlifyで公開する方法

こんにちは、フロントエンドエンジニアの池田です!
新卒入社してから8ヶ月が経ち、最近ではWordpressの案件を進めることが多くなってきました。
今後はVue.jsやNuxt.jsを用いて制作する案件にアサインされる機会が多くなると思い、プライベートでNuxt.jsとWP REST APIをつかって制作したブログサイトについて今回は簡単にまとめてみました。

はじめに

早速ですが、完成したブログサイトはこちら
https://tips-blog.netlify.app/
今回は制作した静的サイトをNetlifyで公開するまでの流れを書いていこうと思います。

Netlifyとは、静的サイトを簡単にホスティングできるサービスです。

前提

フロントエンド: Nuxt(v2.15.8)のSSG
ヘッドレスCMS: WordPress(v6.x.x)
ホスティングサービス: Netlify
コード管理: GitHub

WP REST APIとの連携

WP REST APIのエンドポイントを指定

投稿一覧を取得したい場合は

/wp-json/wp/v2/posts

カテゴリー情報を取得したい場合は

/wp-json/wp/v2/categories

のようになるのですが、今回は以下のよう指定し、
デフォルトの10記事までしか取得できないところを最大100記事取得できるようにします。

/wp-json/wp/v2/posts?per_page=100

パラメータのオプションを他にも知りたい場合は以下をご覧ください。

Posts | REST API Handbook | WordPress Developer Resources
Schema The schema defines all the fields that exist within a post record. Any response from these endpoints can be expected to contain the...
https://developer.wordpress.org/rest-api/reference/posts/#arguments


プロジェクトのルートディレクトリに.envファイルを作成する

WP_BASE_POSTS_URL=[WordPressのURL]/wp-json/wp/v2/posts?per_page=100
//nuxt.config.jsファイル内
.
.
  publicRuntimeConfig: {
    allPostsUrl: process.env.WP_BASE_POSTS_URL
  }
.
.

Nuxt.jsで静的サイトを生成

(今回はレイアウトの構築の手順については割愛します、、)

ここでは非同期処理でAPIを読み出すライブラリaxiosを使用してWordPress内の記事を取得します。
既にNuxt.jsでプロジェクトを作成した際に、ライブラリを追加している場合は必要ありませんが、
もし入っていない場合は以下のコマンドでインストールし、nuxt.config.jsに記述を追加します。
(パッケージマネージャーはYarnを使用しています。)

//npmを使用している場合
$ npm install --save @nuxtjs/axios
//Yarnを使用している場合
$ yarn add -D @nuxtjs/axios
//nuxt.config.js
.
.
modules: {
    '@nuxtjs/axios',
},

// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
     baseURL: '/'
},
.
.

ここまできたら実際にHTTPS通信するのですが、今回は1ページに最大9つの記事を表示させたいので、「vuejs-paginate」を使用してページネーションを実装しています。

//indev.vue

<template lang="pug">
section.-item.section
  .section__main
    news-list.box(:list="items")
    paginate.postsPager__list(v-if="(getPageCount > 1)"
      :page-count="getPageCount"
      :page-range="3"
      :margin-pages="2"
      :click-handler="clickCallback"
      :prev-text="'<<'"
      :next-text="'>>'"
      :page-class="'postsPager__item'"
      :page-link-class="'postsPager__itemLink'"
      :prev-class="'c-pagination-btn c-pagination-prev'"
      :prev-link-class="'c-pagination-btn__link'"
      :next-class="'c-pagination-btn c-pagination-next'"
      :next-link-class="'c-pagination-btn__link'"
      :hide-prev-next="true")
</template>

<script>
export default {
  name: 'NewIndexPage',
  async asyncData (context) {
    const baseUrl = context.$config.allPostsUrl
    const items = await context.$axios.$get(baseUrl)
    const parPage = 9
    const currentPage = 1
    return {
      items,
      parPage,
      currentPage
    }
  },
  data () {
    return {
      items: '',
      parPage: '',
      currentPage: ''
    }
  },
  computed: {
    posts: function () {
      const current = this.currentPage * this.parPage
      const start = current - this.parPage
      return this.items.slice(start, current)
    },
    getPageCount: function () {
      return Math.ceil(this.items.length / this.parPage)
    }
  },
  methods: {
    clickCallback: function (pageNum) {
      this.currentPage = Number(pageNum)
    }
  }
}
</script>
// 親コンポーネント

<template lang="pug">
.newsList
  news-list-card.newsList__item(v-for="(item, index) in list" :key="`news-${index}`" :post="item")
</template>

<script>
export default {
  name: 'NewsList',
  props: {
    list: {
      type: Array,
      default: () => [],
      required: true
    }
  }
}
</script>
// 子コンポーネント

<template lang="pug">
.card
  nuxt-link.card__link(:to="`/news/posts/${post.id}`")
    p.card__title {{ post.title.rendered }}
    p.card__date  {{ post.date | dateFilter }}
</template>

<script>
export default {
  name: 'NewsListCard',
  props: {
    post: {
      type: Object,
      default: () => {},
      required: true
    }
  }
}
</script>

記事の部分については、コンポーネント化していますが、ここで重要なのはWordPressの記事を取得している以下の箇所です。(便宜上、vuejs-paginateのソースを削除しています。)

//indev.vue

<template lang="pug">
section.-item.section
  .section__main
    news-list.box(:list="items")
・
・
・
</template>

<script>
export default {
  name: 'NewIndexPage',
  async asyncData (context) {
    const baseUrl = context.$config.allPostsUrl
    const items = await context.$axios.$get(baseUrl)
    return {
      items
    }
  }
・
・
・
}
</script>

開発モードで起動しているローカル環境で記事を確認できたら完了です。

generateコマンドでの静的ファイルを生成

//プロジェクトディレクトリ上
$ yarn generate

このように プロジェクトディレクトリでyarn generateコマンドを実行すると
dist フォルダに静的ファイルが出力されます。

最後にyarn startコマンドでローカル環境を本番モードで起動して制作したサイトが表示されれば完了です!ここまでできたら、あとはNetlifyで公開設定を行います。

//プロジェクトディレクトリ上
$ yarn start

Netlifyで静的サイトを公開する

今回はGithubと連携して、mainブランチが更新されるたびに自動デプロイがされるように設定します。
手順は以下の通りです。

1. NetlifyにGithubアカウントでログイン(https://netlify.com/


2.「Add new site」をクリックし、「Import an existing project」を選択する。


3. ホスティング対象のリポジトリを選択する。


4. Branch to deploy (対象のブランチ)やPublish directory (公開するディレクトリ)の設定を必要に応じて追加する。今回は以下のように設定しました。

5. 最後に「Deploy site」をクリックして公開します。


以上で 公開設定が完了です。
画面に表示されている URL をクリックすることで公開したサイトを確認できます。

おわりに

今回はNuxt.jsとWP REST APIで制作したサイトをNetflifyで公開する手順を簡単にご紹介しました。

コムデではVue.jsやNuxt.jsの案件が増えてきており、入社してすぐにそのようなモダンな技術を使用したプロジェクトに入っている者もたくさんいます。もちろん、基礎的な技術力は必要だと思いますが、技術に対して真摯に向き合う姿勢がかわれてアサインされるケースが多々あります。
この記事を見て、Vue.jsやNuxt.jsを用いたWeb制作に興味を持った方、なにか疑問に思われた方は、ぜひ一度弊社のエンジニアとお話しすると良いと思います!

自分自身もプロジェクトにメインで参画できるように、今後も学ぶ姿勢を忘れずコーディングを楽しんでいきたいです!ご一読ありがとうございました︎!

Invitation from 株式会社コムデ
If this story triggered your interest, have a chat with the team?
株式会社コムデ's job postings
15 Likes
15 Likes

Weekly ranking

Show other rankings
Like 池田 力斗's Story
Let 池田 力斗's company know you're interested in their content