40
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Nuxt/Content で Markdown なブログ・お知らせサイト作る

Last updated at Posted at 2020-05-27

Nuxt 3 / Nuxt Content 2.9 向けの更新記事を以下に記載しましたのでこちらも参考になさってください。↓


Yo 我らすぐブログ作るけど中身更新しなーい

三行

  • @Nuxt/Content ってやつの v1.0.0 が公開された
  • Nuxt.js で Markdown ブログとかニュースページを作るのが死ぬほど簡単になった
  • Markdown ファイルとか JSON から Nuxt.js へ受け渡しをいい感じにやってくれるモジュールだよ

作ってみよう

package.json と nuxt.config.js を準備

package.json
{
  ...
  "scripts": {
    "dev": "nuxt",
    "generate": "nuxt generate"
  },
  "dependencies": {
    "@nuxt/content": "^1.0.0",
    "nuxt": "^2.12.2"
  }
}
nuxt.config.js
  ...
  modules: [
    '@nuxt/content'
  ],

レポジトリ構造

content ディレクトリを作って、 md ファイルを入れます。
pages ディレクトリに news ディレクトリを切って、ここに詳細ページと一覧を表示します。

% tree . -N
.
├── content
│   └── news
│       ├── 20200526.md
│       └── 20200527.md
├── layouts
│   └── default.vue
├── node_modules
├── nuxt.config.js
├── package-lock.json
├── package.json
├── pages
│   ├── index.vue
│   └── news
│       ├── _slug.vue
│       └── index.vue
└── static
    └── images
        └── news
            ├── sample26.png
            └── sample27.png

一覧に表示: content ディレクトリから md を拾ってくる

news/index.vue
<template>
  <div>
    <div v-for="n in news" :key="n.slug">
      <nuxt-link :to="'/news/'+ n.slug">{{n.title}} {{n.date}}</nuxt-link>
    </div>
  </div>
</template>

<script>

export default {
  async asyncData ({ $content, params }) {
    const query = await $content('news' || 'index').limit(15)
    const news = await query.fetch()
    return { news }
  }
}
</script>

詳細を表示: content ディレクトリから md を拾ってくる

news/_slug.vue
<template>
  <article>
    <h1>{{news.title}}</h1>
    <dl>
      <dt>date</dt>
      <dd>{{news.date}}</dd>
    </dl>
    <div><img :src="news.image" /></div>
    <div v-for="tag in news.tags" :key="tag">{{tag}}</div>
    
    <nuxt-content :document="news" />
  </article>
</template>

<script>
export default {
  async asyncData ({ $content, params }) {
    const news = await $content('news', params.slug || 'index').fetch()
    return { news }
  }
}
</script>

実際に実行してみて、起動できるかチェック

% npm run dev

localhost:3000

生成もしてみる

以下 generate を nuxt.config.js に追加しておこう (今最新の Nuxt 2.12 までは)

nuxt.config.js
  generate: {
    // Nuxt 2.13+ では、これすらいらなくくなるらしい(すごい)
    async routes () {
      const { $content } = require('@nuxt/content')
      const files = await $content('news' || 'index').fetch()

      return files.map(file => file.path === '/index' ? '/' : file.path)
    }
  }
% npm run generate

> nuxt-content-web@1.0.0 generate /Users/takahashi.nobuhiro/git/web/nuxt-content-web
> nuxt generate

Entrypoint app = server.js
ℹ Generating pages                                                               14:00:07
✔ Generated /news/20200526                                                       14:00:07
✔ Generated /news                                                                14:00:07
✔ Generated /                                                                    14:00:07
✔ Generated /news/20200527                                                       14:00:07

動的なファイルも SSG される

上記サンプルソースコード

ほかなにができるの

  • Vue Component を Markdown に埋めるとかできる
    • MDX みがある
    • Twitter Component 作って埋め込めたり nuxt-link とか書けるのでいいね
  • Markdown のホットリロードとかも用意されて快適
  • テキスト検索とかも用意されている
  • シンタックスハイライトも実装済み
  • Hooks 構造体を追加して、カスタムアクションとかも追加できる

かんそう

  • GitHub ベースの Headless CMS アーキテクチャなサイトにめっちゃ良さそう
  • いろんな人が Markdown 書けるようになって git の基礎的な操作ができるようになったらいいなぁ

個人サイトも先日このスタックで作り直しました。

40
41
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?