next.config.js

next.config.jsとは

Next.jsプロジェクトの設定を行うための重要なファイル

一般的な設定項目

const nextConfig = {
  // リアクトの厳格モードを有効化
  reactStrictMode: true,

  // 画像最適化の設定
  images: {
    domains: ['example.com'],
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
  },

  // 環境変数の設定
  env: {
    customKey: 'my-value',
  },

  // ウェブパックの設定をカスタマイズ
  webpack: (config, { isServer }) => {
    // カスタムウェブパック設定をここに追加
    return config
  },

  // 国際化の設定
  i18n: {
    locales: ['en', 'fr', 'ja'],
    defaultLocale: 'en',
  },

  // リダイレクトの設定
  async redirects() {
    return [
      {
        source: '/old-blog/:slug',
        destination: '/new-blog/:slug',
        permanent: true,
      },
    ]
  },

  // リライトの設定
  async rewrites() {
    return [
      {
        source: '/api/:path*',
        destination: 'https://api.example.com/:path*',
      },
    ]
  },

  // ヘッダーの設定
  async headers() {
    return [
      {
        source: '/api/:path*',
        headers: [
          { key: 'Access-Control-Allow-Credentials', value: 'true' },
          { key: 'Access-Control-Allow-Origin', value: '*' },
        ],
      },
    ]
  },

  // 出力ディレクトリの設定
  distDir: 'build',

  // 静的ファイルのプレフィックス設定
  assetPrefix: process.env.NODE_ENV === 'production' ? 'https://cdn.example.com' : '',

  // サーバーサイドのランタイム設定
  serverRuntimeConfig: {
    mySecret: 'secret',
    secondSecret: process.env.SECOND_SECRET,
  },

  // クライアントサイドで利用可能な公開ランタイム設定
  publicRuntimeConfig: {
    staticFolder: '/static',
  },
}

module.exports = nextConfig

assetPrefix

  // 静的ファイルのプレフィックス設定
  assetPrefix: process.env.NODE_ENV === 'production' ? 'https://cdn.example.com' : '',

上記だと環境変数をチェックし本番環境と開発環境でURLの前の文字列を切り分けています

output: ‘export’,

next.config.jsファイルにoutput: 'export'を追加することで、Next.jsアプリケーションを静的サイトとしてビルドするよう指示します

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
}

module.exports = nextConfig

この設定により、以下の変更が適用されます:

  1. ビルドプロセスの変更next buildコマンドを実行すると、静的なHTMLファイルが生成されます
  2. 出力ディレクトリ: デフォルトでは、静的ファイルはoutディレクトリに出力されます

outputFileTracingRoot

特にモノレポ構造や複雑なディレクトリ構造を持つプロジェクトで重要です。ファイルトレーシングを正確に行うことで、デプロイメントの最適化や依存関係の管理が改善されます。

これにより、Next.jsが正確に依存関係を把握し、必要な全てのファイルを適切にビルドとデプロイに含めることができます。

最適化されたビルド出力(要なファイルのみが含まれ、不要なファイルは除外されます。)

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    outputFileTracingRoot: process.cwd(),  // または特定のパスを指定
  },
}

module.exports = nextConfig
experimental.outputFileTracingRoot の効果 デフォルト設定 my-monorepo packages shared-ui my-next-app トレーシング範囲 outputFileTracingRoot 設定後 my-monorepo packages shared-ui my-next-app 拡大されたトレーシング範囲 黄色の領域がトレーシングの対象となります。設定により、範囲が拡大されています。

trailingSlash

URL 末尾にスラッシュ(/)を付けるかどうかを制御します。

/** @type {import('next').NextConfig} */
const nextConfig = {
  trailingSlash: true, // または false
}

module.exports = nextConfig

設定値と動作

  1. trailingSlash: true
    • すべての URL の末尾にスラッシュが追加されます。
    • 例: /about/about/
  2. trailingSlash: false (デフォルト)
    • URL の末尾にスラッシュが付きません。
    • 例: /about//about

【Next.js】検証テストのため現在時刻を変更する方法(クライアント側)

━ src
  ┣ app
  ┃ ┗ thanks/page.tsx
  ┣ hooks
  ┃ ┗ useCustomTime.ts

useCustomTime.ts

"use client";
import { useState, useEffect } from 'react';

// mockedTime という変数を作成し、初期値を null に設定します。この変数は、現在の時間を模倣するために使用されます。
// 具体的には、この変数に値が設定されている場合は、その値が現在の時間として使用されます。
let mockedTime: Date | null = null;

// mockedTime に time の値を設定します。
export const setMockedTime = (time: Date | null) => {
  mockedTime = time;
};

// useState と useEffect を使用して、現在の時間を取得します。さらに、mockedTime が設定されている場合は、その値を返します。
export const useCustomTime = (initialTime = new Date()) => {
  const [currentTime, setCurrentTime] = useState(mockedTime || initialTime);

  useEffect(() => {
    if (mockedTime) return;

    const timer = setInterval(() => {
      setCurrentTime(new Date());
    }, 1000);

    return () => clearInterval(timer);
  }, []);

  return currentTime;
};

thanks/page.tsx

"use client";
import { setMockedTime, useCustomTime } from "@/hooks/useCustomTime";

export default function Thanks() {

    // 現在時刻を取得する関数
    // const getTime = () => {
    //     const date = new Date()
    //     const hour = date.getHours()
    //     const minute = date.getMinutes()
    //     const second = date.getSeconds()
    //     return `${hour}:${minute}:${second}`
    // }

    // setMockedTime 関数を使用して、現在時刻を任意の時間に設定します。
    setMockedTime(new Date(2023, 0, 1, 13, 0, 0)); // 2023年1月1日の3時0分0秒に設定

    const currentTime = useCustomTime()
    const getTime = () => {
        const hour = currentTime.getHours()
        const minute = currentTime.getMinutes()
        const second = currentTime.getSeconds()
        return `${hour}:${minute}:${second}`
    }


    // 営業時間内かどうかをチェック営業時間
    const checkTime = () => {
        const time = getTime()
        const timeArray = time.split(':')
        const hour = Number(timeArray[0])
        const minute = Number(timeArray[1])
        const second = Number(timeArray[2])

        // 営業時間外の場合はfalseを返す
        if(hour < 7 || hour > 20) {
            return false
        }
        // 営業時間内 trueを返す
        else {
            return true
        }
    }

    return (
        <>
        <div>
            {checkTime() ? (
                <p>ありがとうございました。営業時間内にお問い合わせいただいたため、返信までにお時間をいただく場合がございます。</p>
            ) : (
                <p>ありがとうございました。営業時間外にお問い合わせいただいたため、翌営業日以降に返信いたします。</p>
            )}
        </div>
        </>
    )
}