Nuxt + Nuxt UI + Nuxt Content でブログを作ってみた

Nuxtと公式モジュールを活用して、ポートフォリオ兼ブログサイトを構築した記録と学びをまとめます。

この記事は約 6 分で読めます

🚀 はじめに

はじめまして、Nao です。
2022 年 4 月から東京でシステムエンジニアとして働いています。

Nuxt を使って自分のポートフォリオ兼ブログサイトを作成しました。
主なコンテンツとしては、技術ブログやエッセイを書こうかなと思っています。

せっかく書くなら人に読まれたいので、色々試行錯誤してみます。

このサイト自体の開発について、開発中に感じたことや 工夫したポイント、つまづきポイントなどを
ブログ開発タグで書いていくので、自分で Web サイトを作ろうとしている人や技術選定の参考になれば幸いです。

主な使用技術と選定理由

Nuxt v4

  • フルスタック Vue フレームワーク
  • 公式ライブラリ・エコシステムが充実している
  • Vue.js を仕事で触った経験があり、Nuxt の概念にある程度馴染みがある。Next.js の人気を横目に採用を決意

Nuxt: The Full-Stack Vue Framework

Build fast, production-ready web apps with Vue. File-based routing, auto-imports, and server-side rendering — all configured out of the box.

https://nuxt.com/

Nuxt Content v3

  • Nuxt 公式 CMS ライブラリ
  • Markdown 等で記事を作成して Git 管理できる
  • Nuxt UI とのシナジーがある

The git-based CMS for Nuxt projects

Nuxt Content is a module for Nuxt that provides a simple way to manage content for your application, within your git repository. It allows developers to write their content in Markdown, YAML or JSON files and then query and display it in their application.

https://content.nuxt.com/

Nuxt UI v4

  • Nuxt 公式 UI ライブラリ
  • Reka UI + Tailwind CSS + Tailwind Variants で構築・スタイリングされており、カスタマイズ性も高い
  • Nuxt UI v3 では通常版と Pro 版に分かれていたが、Vercel の買収1 2 3により v4 で統合された
  • 現在は 100 個以上のコンポーネントが無償で利用可能
  • Nuxt Content とのシナジーがある

The Intuitive Vue UI Library - Nuxt UI

A comprehensive Vue UI component library (Nuxt optional) with 125+ accessible, Tailwind CSS components for building modern web applications. Works with Nuxt and plain Vue apps (Vite, Inertia, SSR).

https://ui.nuxt.com/

Nuxt Hub

  • Nuxt 公式のオールインワンなホスティング & バックエンドサービス。Cloudflare を活用したフルスタック PaaS

Build full-stack Nuxt applications. · NuxtHub

https://hub.nuxt.com/

🧭 サイト構成

URL概要 (機能)
共通 (ヘッダー)全文検索、カラーモード選択
/トップページ(CTA、タグ、最新記事)
/aboutプロフィールページ(スキルや経歴、SNS リンクなど)
/article記事一覧ページ(タグ検索)
/article/[...slug]記事詳細ページ

タグの数によっては、今後タグ一覧みたいな画面を追加するかも

環境構築

VSCode で Dev Container を使用して開発します。
Dev Container の使い方については当記事内では掘り下げません。(後日追加するかも)

拡張機能 ID: ms-vscode-remote.remote-containers

Dev Containers - Visual Studio Marketplace

Extension for Visual Studio Code - Open any folder or repository inside a Docker container and take advantage of Visual Studio Code's full feature set.

https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers

コンテナ作成

今回はプロジェクト名を blog-nuxt とし、コンテナ内の /workspace へマウントするように作成します。
(違う名前を付けたい時は読み替えてください)

mkdir blog-nuxt

Dockerfile の作成

Dockerfile
FROM node:lts-slim

WORKDIR /workspace

RUN apt-get update && apt-get install -y git && npm install -g pnpm@latest

今回は node:lts-slim イメージをベースにします。
パッケージマネージャには pnpm を使用します。

Docker Compose ファイルの作成

compose.yaml
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - .:/workspace:cached
    ports:
      - 3000:3000
      - 4000:4000
    tty: true
    environment:
      TZ: Asia/Tokyo

開放しているポートの 3000 は開発サーバー、4000 は Nuxt Content のホットリロード機能が利用します。
services.app.volumesblog-nuxt をコンテナ内の /workspace ディレクトリへマウントします。

Dev Container ファイルの作成

.devcontainer/devcontainer.json
{
  "name": "Nuxt",
  "dockerComposeFile": "../compose.yaml",
  "service": "app",
  "workspaceFolder": "/workspace",
  "customizations": {
    "vscode": {
      "settings": {
        "terminal.integrated.shell.linux": "/bin/bash",
        "editor.formatOnSave": true
      },
      "extensions": [
        "bradlc.vscode-tailwindcss",
        "editorconfig.editorconfig",
        "esbenp.prettier-vscode",
        "mikestead.dotenv",
        "nuxt.mdc",
        "nuxtr.nuxtr-vscode",
        "vue.volar"
      ]
    }
  }
}

おすすめの拡張機能

拡張機能は好みが出るところですが、公式ドキュメントで推奨されているものはインストールしておいたほうが良いでしょう。
※コンテナ作成後に追加することもできます。

リンクID備考 - 推奨しているライブラリ
Tailwind CSS IntelliSensebradlc.vscode-tailwindcssNuxt UI 公式ドキュメント
EditorConfig for VS CodeEditorConfig.EditorConfig複数の Nuxt 公式リポジトリで使用している
MDC - Markdown ComponentsNuxt.mdcNuxt Content 公式ドキュメント
NuxtrNuxtr.nuxtr-vscodeNuxt 公式ドキュメント
Vue (Official)Vue.volarVue.js 公式ドキュメント

Nuxt プロジェクト作成

プロジェクトの作成とライブラリのインストールコマンド、セットアップ方法を解説しますが、 鮮度の良い最新の公式ドキュメントも参照して実施してください。

コンテナに入る

blog-nuxt を開いた状態で「コンテナーで再度開く」を押下し、コンテナ内に入って作業します。

または

create nuxt

コンテナ作成で設定したとおり、カレントディレクトリは /workspace になります。
ここに Nuxt アプリを作成していきます。

pnpm create nuxt@latest .

上記コマンドを実行すると、対話方式でインストールが進みます。

create nuxt@latest

        .d$b.
       i$$A$$L  .d$b
     .$$F` `$$L.$$A$$.
    j$$'    `4$$:` `$$.
   j$$'     .4$:    `$$.
  j$$`     .$$:      `4$L
 :$$:____.d$$:  _____.:$$:
 `4$$$$$$$$P` .i$$$$$$$$P`

 Welcome to Nuxt!
 Creating a new project in /workspace.

 The directory /workspace already exists. What would you like to do?
 Override its contents
 Select different directory
 Abort

 Which package manager would you like to use?
 npm
 pnpm
 yarn
 bun
 deno

 Initialize git repository?
 Yes / No

 Would you like to install any of the official modules?
 Yes / No

 Pick the modules to install:
 @nuxt/content The file-based CMS with support for Markdown, YAML, JSON
 @nuxt/eslint Project-aware, easy-to-use, extensible and future-proof ESLint integration
 @nuxt/fonts Add custom web fonts with performance in mind
 @nuxt/icon Icon module for Nuxt with 200,000+ ready to use icons from Iconify
 @nuxt/image Add images with progressive processing, lazy-loading, resizing and providers support
 @nuxt/scripts Add 3rd-party scripts without sacrificing performance
 @nuxt/test-utils Test utilities for Nuxt
 @nuxt/ui The Intuitive UI Library powered by Reka UI and Tailwind CSS

 Do you want to install `better-sqlite3` package?
 Yes / No

Would you like to install any of the official modules? と聞かれたら、 Yes で使用する公式ライブラリを選択します。

Ignored build scripts: better-sqlite3. のようなメッセージが表示されたら、下記コマンドで許可します。

pnpm approve-builds

初期表示画面確認

インストールが完了したら下記コマンドで起動してみます。

pnpm dev

localhost:3000 にアクセスして Welcome ページが表示されることを確認します。

拡張機能 + ライブラリ等のセットアップ

EditorConfig の設定

.editorconfig
root = true

[*]
indent_size = 2
indent_style = space
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false

VSCode の設定

.vscode/settings.json
{
  "files.associations": {
    "*.css": "tailwindcss"
  },
  "editor.quickSuggestions": {
    "strings": "on"
  },
  "tailwindCSS.classAttributes": ["class", "ui"],
  "tailwindCSS.experimental.classRegex": [
    ["ui:\\s*{([^)]*)\\s*}", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
  ]
}

この設定があることで、下記の嬉しいことがあります。

  1. *.css ファイルを Tailwind CSS として開くよう指定(純正 CSS にない構文の警告が出なくなる)
  2. Tailwind クラスの入力補完
  3. Tailwind クラスによって適用されるスタイルの表示

app/assets/css/main.css の作成

app/assets/css/main.css
@import 'tailwindcss';
@import '@nuxt/ui';

@source "../../../content";

このファイルで Tailwind CSS と Nuxt UI Pro を CSS にインポートします。

pnpm を使用する場合、.npmrc ファイルで shamefully-hoist=true を設定するか、 tailwindcss をインストールする必要があります。
Nuxt UI と Nuxt Content を併用する場合、@source ディレクティブで content ディレクトリを指定します。

Can't resolve 'tailwindcss' in '/workspace/app/assets/css' のようなエラーが発生していたらこれが原因です。

今回は Tailwind CSS のインストールを採用します。

pnpm add tailwindcss @tailwindcss/vite

Installing with Vite - Installation

Integrate Tailwind CSS with frameworks like Laravel, SvelteKit, React Router, and SolidJS.

https://tailwindcss.com/docs/installation/using-vite

nuxt.config.ts を編集

nuxt.config.ts
import tailwindcss from '@tailwindcss/vite'
export default defineNuxtConfig({
  devtools: { enabled: true },

  modules: [
    '@nuxt/eslint',
    '@nuxt/image',
    '@nuxt/ui',
    '@nuxt/content',
    '@nuxt/scripts',
    '@nuxt/test-utils',
  ],

  css: ['~/assets/css/main.css'],
  vite: {
    plugins: [tailwindcss()],
  },
})
modules 配列で @nuxt/ui@nuxt/content より先に読み込む必要があります。

modules 配列: 使用する Nuxt モジュールを登録します。
css 配列: 前述の css ファイルを読み込みます。

app.vue を編集

app/app.vue
<template>
  <UApp>
    <div>
      <NuxtRouteAnnouncer />
      <NuxtWelcome />
    </div>
    <NuxtPage />
  </UApp>
</template>

NuxtRouteAnnouncer , NuxtWelcome コンポーネントを削除し、NuxtPageUApp でラップします。

以上で一旦環境構築は完了です。


Footnotes

  1. GitHub 上でのアナウンス: https://github.com/nuxt/ui/issues/4488
  2. NuxtLab からのアナウンス: https://nuxtlabs.com/
  3. Vercel からのアナウンス: https://vercel.com/blog/nuxtlabs-joins-vercel