ロゴテキスト ロゴ

    Nuxt/Contentのcontentフォルダの階層を深くする

    Nuxt/Contentのcontentフォルダの階層を深くする

    Nuxt/Contentで記事を書いていくと記事フォルダの階層を深くしたくなります。


    私の場合、記事をカテゴリで分けたくなりました例えば以下のように。

    content/
      articles/
        Next/
          next-article-01.md
        Nuxt/
          nuxt-article-01.md
          nuxt-article-02.md
          nuxt-article-03.md
        ServerlessFramework/
          serverless-framework-article-01.md
          serverless-framework-article-02.md

    このようにした場合、記事取得時の処理の書き方が少し特殊になります。


    Nuxt/Contentのv1.3.0以上にのみ対応しているので、それ以下だと動きません。

    一覧記事の取得

    重要な点は $content の第2引数に {deep: true} を指定するところ。

    <script lang="ts">
    import { Context } from '@nuxt/types'
     
    export default {
      async asyncData({ $content, params }: Context) {
        const articles = await $content('articles', { deep: true }).fetch()
        return { articles }
      },
    }
    </script>

    {deep: true} を指定しない場合は articles/ 直下のファイルのみしか取得出来ませんが、 これで階層が深くなったファイル群も取得出来ます。

    1記事のみを取得する

    記事詳細ページでは以下のように取得するのが主流です(公式のコードを参考)

    export default {
      async asyncData({ $content, params }) {
        const article = await $content('articles', params.slug).fetch()
     
        return {
          article
        }
      }
    }

    これは内部的に $content('article', params.slug)/articles/${params.slug} に変換されます。


    例えば https://hogehoge.com/articles/sample-01 というURLにアクセスした場合、 articles/sample-01 となり以下の「sample-01.md」を参照してくれます。

    articles/
      sample-01.md


    しかし残念ながらこの方法だと階層を深くした場合に対応していません。


    もちろんNuxtのフォルダを使ったルーティング方法を用いてカテゴリ名を渡しつつ、という事をすれば出来ますが、 URLと記事のフォルダ階層を常に同じにしなければいけなくなります。



    そこで少し無理矢理ですが記事を取得する際に where を使って対応してみます。

    <script lang="ts">
    import { Context } from '@nuxt/types'
     
    export default {
      async asyncData({ $content, params }: Context) {
        const articles = await $content('articles', { deep: true }).where({ slug: params.slug }).fetch()
        if (articles.length === 0) {
          // TODO: 存在しない記事、404へ
          return
        }
        const article = articles[0]
        return { article }
      },
    }
    </script>

    全ての記事を取得後、 where を用いて該当するslugの記事を取得しています。 この場合結果が配列で渡されるため、 [0] で先頭記事を取得して完了です。

    余談

    記事の取得方法はNuxt Contentの公式ページ上がっています。

    コンテンツを取得する - Nuxt Content

    取得方法色々ありますね、サンプルも豊富で嬉しい! 😁

    プロフィールの背景画像 プロフィール画像
    Yuki Takara
    都内でフリーランスのエンジニアをやってます。フロントとアプリ開発メインに幅広くやってます。