Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
51
Help us understand the problem. What is going on with this article?
@tetsushi-ito

Nuxt.jsでGatsbyJS的なことができるnuxt/contentを試してみる

GatsbyJSとは?

GatsbyJSとは、React製の静的サイトジェネレーターです。

  • UIはReactで構築
  • データは article.md のようなマークダウンで作る
  • ビルドすることで、トップページ・タグアーカイブ・記事個別ページなどなど必要なファイルを .html で生成する

こんなことができます。
静的HTMLファイルなので、Netlify / AWS Amplify Console / Firebase Hosting等にデプロイすれば非常に低コストで運用できます。
データベース等も使わないので、万が一急にアクセスが増えても、先述のようなホスティングサービスを利用していればまず問題なく捌けます。

以前ポートフォリオサイトとブログをGatsbyJSで作ってみましたが、データの取得にGraphQLを使う部分や、各ページを生成するロジックを実装するあたりでかなりてこずってしまい、「できればNuxt.jsでやりたいなー」と思っていました。

nuxt/contentが出た!

2020/5/24にnuxt/contentがバージョン1.0.0を迎えました!
https://github.com/nuxt/content

本家サイト( https://content.nuxtjs.org/ )も非常にシンプルでわかりやすく、簡単にサンプルを組み立てることができました。
内容としてはまさに欲しかったものです!

使ってみる

  • yarnをインストールする(省略)
  • Nuxt.jsプロジェクトを作成する
# プロジェクトを作成
$ yarn create nuxt-app nuxt-content-blog

# オプションは全てデフォルトにしました
? Project name nuxt-content-blog
? Project description My tiptop Nuxt.js project
? Author name tetsushi
? Choose programming language JavaScript
? Choose the package manager Yarn
? Choose UI framework None
? Choose custom server framework None (Recommended)
? Choose Nuxt.js modules (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Choose linting tools (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Choose test framework None
? Choose rendering mode Universal (SSR)
? Choose development tools (Press <space> to select, <a> to toggle all, <i> to invert selection)

# ディレクトリを移動
$ cd nuxt-content-blog

# ローカルサーバーを起動
$ yarn dev

http://localhost:3000/ にアクセスすると以下のようないつもの画面が表示されます。

スクリーンショット 2020-06-02 08.42.46.png

  • nuxt/contentをインストールする

公式ドキュメントに沿って進めればハマるところはありませんでした。
https://content.nuxtjs.org/installation

$ yarn add @nuxt/content
  • nuxt.config.js を調整する
{
  modules: [
    '@nuxt/content' // これを追加
  ],
}

これであっさり準備完了です。
ディレクトリ構造はこのようになりました。

$ tree -I node_modules
.
├── README.md
├── assets
│   └── README.md
├── components
│   ├── Logo.vue
│   └── README.md
├── layouts
│   ├── README.md
│   └── default.vue
├── middleware
│   └── README.md
├── nuxt.config.js
├── package.json
├── pages
│   ├── README.md
│   └── index.vue
├── plugins
│   └── README.md
├── static
│   ├── README.md
│   └── favicon.ico
├── store
│   └── README.md
└── yarn.lock

記事ファイルを置いてみる

ブログを作るイメージで、記事を書いてみます。
content/articles というディレクトリを作り、 article-1.mdarticle-2.md を作成しました。

$ tree content/
content/
└── articles
    ├── article-1.md
    └── article-2.md

content/articles/article-1.md の内容は以下です。

content/articles/article-1.md
---
title: 記事1
tags: [Nuxt.js JavaScript]
---

# 見出し1

## 見出し2

本文本文

content/articles/article-2.md にも同じような内容を書きました。
これで記事は準備完了です。

一覧ページを作ってみる

ブログのトップページをイメージして、記事一覧を出力してみます。
トップページ(/)にページを作るので、 pages/index.vue を作成します。

pages/index.vue
<template>
  <div>
    <div v-for="article in articles">
      <nuxt-link :to="article.path">{{ article.title }}</nuxt-link>
    </div>
  </div>
</template>

<script>
export default {
  components: {},
  async asyncData({ $content }) {
    const articles = await $content("articles")
      .limit(5)
      .fetch();

    return {
      articles
    };
  }
};
</script>

asyncData 関数でクエリを組み立てます。
クエリはLokiJSというインメモリデータベースライブラリで組み立てます。
https://github.com/techfort/LokiJS

これだけのコードであっという間に素朴なトップページが出来上がってしまいました。

スクリーンショット 2020-06-02 08.54.10.png

リンク先は article.path としています。
content/articles/article-1.md というファイルを作ったので、デフォルトではこの投稿のパスは /articles/article-1 となります。

記事個別ページのテンプレートはまだないので、クリックしてもエラーになります。
では、次に記事個別ページを作ります。

記事個別ページを作る

記事個別ページは /articles/{slug} にします。
pages/articles/_slug.vue を作成しました。

pages/articles/_slug.vue
<template>
  <div class="container">
    {{ article.title }}

    <nuxt-content :document="article" />
  </div>
</template>

<script>
export default {
  components: {},
  async asyncData({ $content, params }) {
    const article = await $content(`articles/${params.slug}`).fetch();

    return {
      article
    };
  }
};
</script>

これで個別ページも完成です。

スクリーンショット 2020-06-02 08.57.42.png

まとめ

記事の配列を得る方法と、単一の記事を得る方法をまず調べました。
これさえあればあとはタグアーカイブを作ったり、ページネーションを作ったりすることはさほど苦労しないかと思います。

見た目を整えるのは普通のVue.js / Nuxt.jsの開発と同じようにコンポーネントを作ってやっていけそうです。

普段はAngularで開発していますが、React / VueのHMRは非常に便利です。
ブログ執筆等では、なんならWordPress等のCMSよりも書きやすいかもしれません。

コンテンツがDBではなくGitで管理できるのも魅力的です。
必要な実装方法を調べ終わったらどんどんGatsbyJSから乗り換えて行こうかと思います。

51
Help us understand the problem. What is going on with this article?
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
tetsushi-ito
ポートフォリオ → github.com/tetsushi-ito/resume / Ionic / Angular / TypeScript / AppSync / DynamoDB / Firebase モバイルアプリとそのバックエンドを開発しています。Twitter → @tetsushi_ito_

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
51
Help us understand the problem. What is going on with this article?