Help us understand the problem. What is going on with this article?

Nuxt.jsとContentfulでブログ作ってみた

More than 1 year has passed since last update.

これは Vue.js #3 Advent Calendar 2017 – Qiita 21日目の記事です。

nuxt_ctf.jpg


Nuxt.js 使ってみたいけど何をつくろうかな〜と思案していたらば、『SEO、OGP……Vue.js製SPAの「困った」を解決できる「Nuxt.js」が便利だ!』という記事でブログを作っていたので、なんだかちょうどよさそうと思い以下を追加してやってみることにしました。

  1. Contentful から記事を取得する
  2. トップページに配置するコンポーネント( components/PostPreview.vue )をつくる
  3. 記事一覧ページと個別記事ページをつくる
  4. nuxt generate で静的ファイルを生成する
  5. GitHub Pages にデプロイ

Nuxt.js ってどんなもんじゃ?という方の参考になれば幸いです :upside_down:

0. とりあえず準備

0-1. Contentful にアカウントを作ったり

Contentful:ドイツのスタートアップ Contentful が開発した、 API に焦点を当てたコンテンツ管理システム(CMS)

以下の記事を参考にして、

以下までを終わらせる。

  • アカウント作成
  • スペース作成
  • Content Delivery API キー作成
  • API キーを .contentful.json に設定

0-2. Nuxtのアプリケーションのベースのセットアップをしたり

SEO、OGP……Vue.js製SPAの「困った」を解決できる「Nuxt.js」が便利だ!』の以下までをちまちまとやって、アプリケーションの大枠を作る。

  1. 「アプリケーションのセットアップと設定」
  2. 「ページレイアウトの操作」
  3. 「ブログのTOPページを作成する」
  4. 「Aboutページの作成」

0-3. 必要なパッケージを追加インストールしたりすると

npm install --save contentful
npm install --save vue-markdown
npm install --save-dev push-dir

0-4. こんなディレクトリになっているのではないかな...?

-| .nuxt/
-| components/
-| layouts/
-| middleware/(今回は使わない)
-| node_modules/
-| pages/
---| about.vue
---| index.vue
-| plugins/
---| contentful.js
-| static/
-| store/(今回は使わない)
-| .contentful.json
-| .editorconfig
-| .eslintrc.js
-| .gitignore
-| nuxt.config.js
-| package.json
-| README.md

1. Contentful から記事を取得する

pages/index.vue で非同期データを取得します。

pages/index.vue
asyncData ({ env }) {
  return client.getEntries({
    'content_type': env.CTF_BLOG_POST_TYPE_ID,
    order: '-fields.publishDate',
    'limit': 3
  }).then(entries => {
    return {
      posts: entries.items
    }
  }).catch(console.error)
}

:hushed: へ〜、 Nuxt.js には asyncData メソッドっていうのがあるのね。
https://ja.nuxtjs.org/guide/async-data

2. トップページに配置するコンポーネント(components/PostPreview.vue)をつくる

pages/index.vue で取得した非同期データをコンポーネントに渡します。

pages/index.vue
<PostPreview :posts="posts"></PostPreview>
components/PostPreview.vue
export default {
  props: ['posts']
}

:rolling_eyes: あ、 asyncData メソッドはページコンポーネントだけで、普通(?)のコンポーネントは持たないのね...。
https://ja.nuxtjs.org/faq/async-data-components/

3. 記事一覧ページと個別記事ページをつくる

Nuxt.js は pages/ ディレクトリ内の Vue ファイルの木構造に沿って、自動的に vue-router の設定を生成してくれます。

記事一覧ページのURLは https://xxxxxxx/posts/ としたいので、 pages/ 配下に posts/ ディレクトリを切り、インデックスのページコンポーネントをつくります。
個別記事ページはContentfulから取得したslugで動的にルーティングしたいので、 アンダーバーをつけたページコンポーネント _slug.vue をつくります。

-| pages/
---| posts/
-----| index.vue // 記事一覧ページ
-----| _slug.vue // 個別記事ページ
---| about.vue
---| index.vue
.nuxt/router.js
routes: [
{
  path: "/",
  component: _5512af1c,
  name: "index"
},
{
  path: "/posts",
  component: _4aea9340,
  name: "posts"
},
{
  path: "/about",
  component: _355ad457,
  name: "about"
},
{
  path: "/posts/:slug",
  component: _4e57d5d0,
  name: "posts-slug"
}
]

:relaxed: 便利...!!
https://ja.nuxtjs.org/guide/routing/

各ページコンポーネントで、非同期データを取得、取得データの表示などをなんやかやします。
個別記事ページへのリンクはなんとなく名前付きルートにしました。

pages/posts/index.vue
<nuxt-link :to="{ name: 'posts-slug', params: { slug: post.fields.slug }}" class="card-footer-item">
  Read More
</nuxt-link>

https://ja.nuxtjs.org/api/components-nuxt-link
https://router.vuejs.org/ja/api/router-link.html

4. nuxt generate で静的ファイルを生成する

何もしないと nuxt generate で生成されるのはルート/ だけです。
そのため、 vue-router で path: "/posts/:slug" と動的に定義されているルーティングを、 generate プロパティの routes にも設定します。

nuxt.config.js
generate: {
  routes () {
    return client.getEntries({
        'content_type': config.CTF_BLOG_POST_TYPE_ID
      }).then((entries) => {
      return [...entries.items.map(entry => `posts/${entry.fields.slug}`)]
    })
  }
},

:neutral_face: 動的なパラメータのときは Promise を返す関数。
https://ja.nuxtjs.org/api/configuration-generate

5. GitHub Pagesにデプロイ

デプロイ用の scripts を追加しましょう。

package.json
"scripts": {
  "dev": "nuxt",
  "build": "nuxt build",
  "start": "nuxt start",
  "generate": "nuxt generate",
  "deploy": "push-dir --dir=dist --branch=gh-pages --cleanup" //これ
},

:slight_smile: GitHub Pages へデプロイするには? https://ja.nuxtjs.org/faq/github-pages

今回はプロジェクトリポジトリにデプロイするので、アプリケーションのベース URL としてリポジトリ名を設定します。

nuxt.config.js
router: {
  base: '/nuxt_blog/'
},

:hushed: この設定をしないと
こうなってほしいのが → https://hisako135.github.io/nuxt_blog/posts
こうなってしまう → https://hisako135.github.io/posts

そして以下コマンドをポチーーーー :point_down_tone2:

npm run generate
npm run deploy

完成

Nuxt.js を初めて使ってみて個人的に「あ、そうなんだ...!」となったことを抜粋しているのでだいぶ端折っていたりあまりエレガントでない部分もありますが、もうちょっとこの子を育てていきたいです2018年。

参考にさせていただいたもの

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした