🍽️

ClientLoggerコンポーネントでNext.jsのブラウザコンソールデバッグを効率化しよう!

に公開

はじめに

Next.js のApp Routerでは、コンポーネントのデフォルトがサーバーサイドコンポーネントになります🖥️

そのため、console.log を実行してもターミナル上に表示され、ブラウザのコンソールには出力されません!

今回は、ブラウザのコンソールログに簡単に出力できる専用コンポーネントをご紹介します🔧

問題:サーバーサイドとクライアントサイドのログ出力

サーバーサイドコンポーネントの場合

// これはターミナルに出力される
export default function ServerComponent() {
  const data = { message: "Hello" }
  console.log(data) // ← ターミナルに表示
  
  return <div>サーバーコンポーネント</div>
}

期待する動作

  • 開発中のデバッグ: ブラウザのコンソールで確認したい
  • データの中身確認: DevToolsで見やすい形で表示したい
  • 簡単な使い方: 既存コードを大きく変更したくない

解決方法:ClientLoggerコンポーネント

ブラウザコンソール専用のログ出力コンポーネントを作成します:

'use client'

import { useEffect } from 'react'

type Props = {
  data: any
  label?: string
  level?: 'log' | 'info' | 'warn' | 'error'
}

export const ClientLogger = ({ data, label, level = 'log' }: Props) => {
  useEffect(() => {
    const output = label ? { [label]: data } : data
    
    switch (level) {
      case 'info':
        console.info(output)
        break
      case 'warn':
        console.warn(output)
        break
      case 'error':
        console.error(output)
        break
      default:
        console.log(output)
        break
    }
  }, [data, label, level])

  return null
}

使い方

基本的な使い方

export default function MyComponent() {
  const userData = { id: 1, name: "田中太郎" }
  
  return (
    <div>
      <ClientLogger data={userData} />
      <p>ユーザー情報を表示</p>
    </div>
  )
}

ブラウザコンソールでの出力:

{id: 1, name: '田中太郎'}

ラベル付きでログ出力

export default function ProductPage() {
  const product = { id: 123, name: "商品A", price: 1000 }
  
  return (
    <div>
      <ClientLogger 
        data={product} 
        label="商品データ" 
      />
      <h1>{product.name}</h1>
    </div>
  )
}

ブラウザコンソールでの出力:

{商品データ: {id: 123, name: '商品A', price: 1000}}

エラーレベルでログ出力

export default function ErrorBoundary() {
  const errorInfo = { message: "APIエラー", status: 500 }
  
  return (
    <div>
      <ClientLogger 
        data={errorInfo} 
        label="エラー詳細"
        level="error"
      />
      <p>エラーが発生しました</p>
    </div>
  )
}

ブラウザコンソールでの出力:

❌ {エラー詳細: {message: 'APIエラー', status: 500}}

API レスポンスのデバッグ

export default async function DataComponent() {
  const response = await fetch('/api/data')
  const data = await response.json()
  
  return (
    <div>
      <ClientLogger 
        data={data} 
        label="API レスポンス" 
      />
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  )
}

ブラウザコンソールでの出力:

{API レスポンス: {users: [{id: 1, name: 'ユーザー1'}, {id: 2, name: 'ユーザー2'}]}}

注意点

開発中の一時的なデバッグ用途

このコンポーネントは 開発中にデータの中身を確認するための一時的なツール です🌞!!

データの確認が終わったら、<ClientLogger /> は必ず削除してください🤞💥

export default function MyComponent() {
  const userData = { id: 1, name: "田中太郎" }
  
  return (
    <div>
      {/* デバッグ用 - 確認後は削除する */}
      <ClientLogger data={userData} label="ユーザーデータ" />
      <p>ユーザー情報を表示</p>
    </div>
  )
}

削除を忘れないために

  • コメントを追加: {/* TODO: デバッグ後削除 */} などを併記
  • コードレビュー: チーム開発では必ずレビューで確認
  • 一時的な使用: 長期間残さず、目的達成後は即座に削除

プリコミット・CIでの自動検知

ClientLogger の削除し忘れを防ぐため、プリコミットやCIで検知する仕組みを導入することをおすすめします😤

ESLintカスタムルール例:

// .eslintrc.js
module.exports = {
  rules: {
    'no-client-logger': 'error', // カスタムルールで ClientLogger 使用を禁止
  },
}

pre-commitフックでの検知:

# .husky/pre-commit
#!/bin/sh
if grep -r "ClientLogger" src/; then
  echo "❌ ClientLogger found! Please remove debug components before commit."
  exit 1
fi

GitHub Actions例:

name: Check Debug Components
on: [push, pull_request]
jobs:
  check-debug:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Check for ClientLogger
        run: |
          if grep -r "ClientLogger" src/; then
            echo "ClientLogger found in source code"
            exit 1
          fi

まとめ

Next.js のApp Routerでは、サーバーサイドコンポーネントとクライアントサイドコンポーネントの違いを理解することが重要です📚

ClientLogger コンポーネントを使うことで:

  • 簡単にブラウザコンソールにログ出力できる
  • 既存コードを大きく変更せずにデバッグ可能
  • ログレベルやラベルで整理された出力

初歩的な内容ですが、初学者の方には意外と盲点になりがちなポイントです💡!!

開発効率アップのお役に立てれば幸いです✨

Discussion