Reactで日本語が文字化けする|UTF-8設定の確認方法

Reactアプリで日本語が文字化けする原因と解決方法を詳しく解説。UTF-8設定の確認方法とエンコーディング問題の対処法を初心者向けに説明します。

Learning Next 運営
32 分で読めます

みなさん、React開発でこんな恐怖を体験したことはありませんか?

「日本語を入力したのに???になってしまう」
「開発環境では大丈夫なのに、デプロイしたら文字化けした」
「APIから取得したデータが読めない文字になってる」

こんな文字化けエラーは、React初心者がよく遭遇する問題です。 でも安心してください!

この記事では、文字化けの原因から具体的な解決方法まで、わかりやすく解説します。 UTF-8設定の確認方法もステップバイステップでご紹介しますね。

文字化けってどうして起こるの?

まずは、なぜ文字化けが発生するのかを理解しましょう。 原因がわかれば、対処法も見えてきます。

文字化けの主な原因

日本語の文字化けは、以下の理由で発生します。

設定系の問題

  • HTMLの文字エンコーディング設定が間違っている
  • ファイル保存時のエンコーディングが違う
  • サーバーの設定が適切でない

データ系の問題

  • APIレスポンスのエンコーディングが合わない
  • ブラウザの設定が影響している

それぞれ解決方法があるので、順番に見ていきましょう。

文字化けのパターンを知っておこう

よくある文字化けパターンをご紹介します。

// こんな感じで表示されていませんか?
const brokenText = "こんにちは"; // → "???" になる
const squareText = "ありがとう"; // → "□□□□□" になる
const weirdText = "今日は晴れ"; // → "莉頃譌・縺ッ譎エ繧�" になる

それぞれ原因が違うので、パターンを覚えておくと対処しやすくなります。

HTMLの設定を確認してみよう

まず最初に確認すべきは、HTMLの文字エンコーディング設定です。 これが間違っていると、ほぼ確実に文字化けします。

public/index.htmlをチェック

Reactアプリのpublic/index.htmlを開いてみてください。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React App</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>

重要なポイントはここです。

1. <meta charset="UTF-8">が必須

これがないと、ブラウザが正しい文字コードを認識できません。 必ず<head>タグの最初の方に配置してください。

2. lang="ja"で日本語を指定

これにより、ブラウザが日本語サイトだと認識します。

3. 大文字・小文字は関係ない

UTF-8でもutf-8でも、どちらでも大丈夫です。

Create React Appの場合

Create React Appで作ったプロジェクトなら、このような形になっているはずです。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Reactアプリケーション"
    />
    <title>React App</title>
  </head>
  <body>
    <noscript>JavaScriptを有効にしてください。</noscript>
    <div id="root"></div>
  </body>
</html>

<meta charset="utf-8" />がしっかり設定されていれば問題ありません。

設定が間違っている場合の修正

もし設定が抜けている場合は、すぐに追加しましょう。

<!-- ❌ 間違った例 -->
<!DOCTYPE html>
<html>
<head>
  <title>React App</title>
</head>

<!-- ✅ 正しい例 -->
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>React App</title>
</head>

この修正だけで、多くの文字化け問題が解決します。

ファイルの保存設定を確認しよう

次に確認すべきは、ファイル自体の保存形式です。 エディタの設定が間違っていると、ファイルが正しく保存されません。

エディタの設定を確認する

VS Codeを例に説明しますね。

ステップ1: エンコーディングを確認

ファイルを開いた状態で、右下を見てください。 「UTF-8」と表示されていれば正常です。

ステップ2: 違う表示になっている場合

「Shift_JIS」や「Windows-1252」などになっていたら、クリックして変更します。 「UTF-8で再オープン」または「UTF-8で保存」を選択してください。

ステップ3: 設定を確認

settings.jsonに以下の設定があると安心です。

{
  "files.encoding": "utf8",
  "files.autoGuessEncoding": true,
  "files.insertFinalNewline": true
}

これで、新しく作るファイルも自動的にUTF-8で保存されます。

ファイル保存時の注意点

ファイルを保存する時は、以下の点に注意してください。

// このような日本語コンテンツがあるファイルの場合
import React from 'react';

function App() {
  return (
    <div>
      <h1>こんにちは、React!</h1>
      <p>日本語のテキストです。</p>
    </div>
  );
}

export default App;

保存時のチェックポイント

  1. エンコーディング: UTF-8を選択
  2. BOM設定: BOM(Byte Order Mark)なしで保存
  3. 改行コード: 環境に合わせて設定(通常はLF)

これらが正しく設定されていれば、ファイル関連の文字化けは防げます。

複数ファイルの一括確認

プロジェクト全体でエンコーディングを確認したい場合は、VS Codeの検索機能を使いましょう。

手順

  1. Ctrl+Shift+Fで検索パネルを開く
  2. 日本語の文字を検索してみる
  3. 文字化けしているファイルがあれば、個別に修正

この方法で、問題のあるファイルを素早く発見できます。

APIデータの文字化けを解決しよう

次は、APIから取得したデータが文字化けする場合の対処法です。 これもよくある問題なので、しっかり解決方法を覚えましょう。

fetch APIの正しい使い方

APIリクエストを送る時は、ヘッダーでエンコーディングを指定します。

const fetchJapaneseData = async () => {
  try {
    const response = await fetch('/api/japanese-data', {
      headers: {
        'Content-Type': 'application/json; charset=utf-8'
      }
    });
    
    if (!response.ok) {
      throw new Error('データの取得に失敗しました');
    }
    
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Error:', error);
  }
};

ポイントはContent-Typeヘッダーにcharset=utf-8を指定することです。

なぜこれが必要なの?

サーバーに「UTF-8で通信しますよ」と伝えることで、文字化けを防げます。 サーバー側も正しい形式でレスポンスを返してくれるようになります。

レスポンスの確認方法

APIからのレスポンスが正しいかチェックする方法もご紹介します。

const checkResponse = async (url) => {
  const response = await fetch(url);
  
  // Content-Typeヘッダーを確認
  const contentType = response.headers.get('content-type');
  console.log('Content-Type:', contentType);
  
  // レスポンスの中身を確認
  const text = await response.text();
  console.log('Response text:', text);
  
  return text;
};

// 使用例
checkResponse('/api/test-japanese')
  .then(result => {
    console.log('取得できたデータ:', result);
  });

この方法で、サーバーから正しいデータが来ているかわかります。

よくある問題と解決法

API関連でよくある問題をまとめました。

問題1: サーバーの設定が間違っている

// サーバー側(Express.jsの例)で修正
app.use(express.json({ 
  charset: 'utf-8' 
}));

app.get('/api/japanese-data', (req, res) => {
  res.setHeader('Content-Type', 'application/json; charset=utf-8');
  res.json({
    message: "こんにちは",
    items: ["項目1", "項目2", "項目3"]
  });
});

サーバー側でもUTF-8を指定することが重要です。

問題2: 外部APIからのデータが文字化け

const fetchExternalData = async () => {
  try {
    const response = await fetch('https://external-api.com/data');
    
    // まずテキストとして取得
    const text = await response.text();
    
    // 文字化けチェック
    console.log('Raw text:', text);
    
    // JSONに変換
    const data = JSON.parse(text);
    return data;
  } catch (error) {
    console.error('外部API取得エラー:', error);
  }
};

外部APIの場合は、まずテキストで取得して中身を確認するのがコツです。

実際のプロジェクトでの対処法

では、実際のプロジェクトでどのように対処すればいいでしょうか? 具体的なケースを見てみましょう。

ユーザー情報表示コンポーネント

ユーザー名などが文字化けする場合の対処法です。

import React, { useState, useEffect } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchUser = async () => {
      try {
        const response = await fetch(`/api/users/${userId}`, {
          headers: {
            'Accept': 'application/json; charset=utf-8'
          }
        });
        
        if (!response.ok) {
          throw new Error('ユーザー情報の取得に失敗');
        }
        
        const userData = await response.json();
        setUser(userData);
      } catch (error) {
        console.error('エラー:', error);
      } finally {
        setLoading(false);
      }
    };

    if (userId) {
      fetchUser();
    }
  }, [userId]);

  if (loading) return <div>読み込み中...</div>;
  if (!user) return <div>ユーザーが見つかりません</div>;

  return (
    <div className="user-profile">
      <h2>{user.name}</h2>
      <p>{user.description}</p>
      <p>メール: {user.email}</p>
    </div>
  );
}

export default UserProfile;

このコードのポイント

  1. Acceptヘッダー: charset=utf-8を指定
  2. エラーハンドリング: 文字化けエラーもキャッチ
  3. ローディング表示: ユーザビリティも配慮

このような形で、確実に日本語データを取得できます。

フォーム送信での文字化け対策

フォームでデータを送信する時の対策も見てみましょう。

import React, { useState } from 'react';

function ContactForm() {
  const [form, setForm] = useState({
    name: '',
    email: '',
    message: ''
  });

  const handleSubmit = async (e) => {
    e.preventDefault();
    
    try {
      const response = await fetch('/api/contact', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json; charset=utf-8'
        },
        body: JSON.stringify(form)
      });
      
      if (!response.ok) {
        throw new Error('送信に失敗しました');
      }
      
      const result = await response.json();
      console.log('送信成功:', result.message);
      
      // フォームをリセット
      setForm({ name: '', email: '', message: '' });
      
    } catch (error) {
      console.error('送信エラー:', error);
    }
  };

  const handleChange = (field) => (e) => {
    setForm(prev => ({
      ...prev,
      [field]: e.target.value
    }));
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>お名前:</label>
        <input
          type="text"
          value={form.name}
          onChange={handleChange('name')}
          placeholder="山田太郎"
        />
      </div>
      
      <div>
        <label>メールアドレス:</label>
        <input
          type="email"
          value={form.email}
          onChange={handleChange('email')}
          placeholder="example@email.com"
        />
      </div>
      
      <div>
        <label>メッセージ:</label>
        <textarea
          value={form.message}
          onChange={handleChange('message')}
          placeholder="お問い合わせ内容を入力してください"
        />
      </div>
      
      <button type="submit">送信</button>
    </form>
  );
}

export default ContactForm;

送信時のポイント

  1. POSTリクエスト: Content-Typecharset=utf-8を指定
  2. JSON変換: JSON.stringify()で正しく変換
  3. プレースホルダー: 日本語例文で親切に

この方法で、送信データも文字化けせずに処理できます。

CSSフォント設定で見た目も完璧に

文字化けが解決しても、フォントが適切でないと読みにくくなります。 日本語に適したフォント設定も覚えておきましょう。

基本的なフォント設定

/* App.css */
body {
  font-family: 
    'Helvetica Neue', 
    Arial, 
    'Hiragino Kaku Gothic ProN', 
    'Hiragino Sans', 
    Meiryo, 
    sans-serif;
  font-feature-settings: "palt";
}

フォント指定のポイント

  1. 欧文フォント: Helvetica、Arialなど
  2. 日本語フォント: ヒラギノ、メイリオなど
  3. フォールバック: sans-serifで最終的に安全策

このように複数のフォントを指定することで、どの環境でも読みやすくなります。

日本語専用のクラス

日本語コンテンツ専用のスタイルも作っておくと便利です。

.japanese-text {
  font-family: 
    'Noto Sans JP',
    'Yu Gothic UI',
    'Yu Gothic',
    'Meiryo',
    'Takao',
    'IPAexGothic',
    'IPAPGothic',
    'VL PGothic',
    'Osaka',
    'MS PGothic',
    sans-serif;
  line-height: 1.7;
  letter-spacing: 0.1em;
}

このクラスを日本語メインのコンポーネントに適用すると、さらに読みやすくなります。

Web フォントの活用

Google Fontsを使うと、より確実に美しい日本語フォントを表示できます。

<!-- public/index.html -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@300;400;700&display=swap" rel="stylesheet">
/* CSS */
.title {
  font-family: 'Noto Sans JP', sans-serif;
  font-weight: 700;
}

.content {
  font-family: 'Noto Sans JP', sans-serif;
  font-weight: 400;
}

Web フォントを使うことで、どのデバイスでも統一された見た目になります。

デプロイ時の設定確認

開発環境では問題ないのに、本番環境で文字化けすることもあります。 デプロイ時の設定も確認しておきましょう。

Netlifyでの設定

Netlifyを使っている場合の設定例です。

# netlify.toml
[build]
  publish = "build"
  command = "npm run build"

[[headers]]
  for = "/*"
  [headers.values]
    Content-Type = "text/html; charset=utf-8"
    X-Content-Type-Options = "nosniff"

この設定により、すべてのページでUTF-8が適用されます。

Vercelでの設定

Vercelの場合は、特に設定しなくても大丈夫なことが多いです。 ただし、APIルートがある場合は確認が必要です。

// pages/api/japanese-data.js
export default function handler(req, res) {
  res.setHeader('Content-Type', 'application/json; charset=utf-8');
  res.status(200).json({
    message: 'こんにちは',
    data: '日本語データ'
  });
}

APIレスポンスでもUTF-8を指定しておけば安心です。

自社サーバーでの設定

自社サーバーを使う場合は、サーバー設定も重要です。

Apacheの場合

# .htaccess
AddDefaultCharset UTF-8

<IfModule mod_mime.c>
  AddCharset utf-8 .html .css .js .json .xml
</IfModule>

Nginxの場合

# nginx.conf
http {
  charset utf-8;
  charset_types text/xml text/plain text/css application/javascript application/json;
}

これらの設定で、サーバーレベルでの文字化けも防げます。

トラブル時のデバッグ方法

それでも文字化けが解決しない場合のデバッグ方法をご紹介します。 手順通りに確認すれば、必ず原因が見つかります。

ブラウザでの確認手順

ステップ1: 開発者ツールを開く

F12キーを押して、開発者ツールを開きます。

ステップ2: Consoleタブでエラー確認

文字化け関連のエラーが出ていないかチェックします。 404エラーが出ている場合は、ファイルパスの問題です。

ステップ3: Networkタブでレスポンス確認

APIリクエストのレスポンスを確認します。 Content-Typeヘッダーにcharset=utf-8があるかチェックしてください。

ステップ4: Elementsタブで文字確認

実際のHTML要素を確認して、どの段階で文字化けしているか特定します。

デバッグ用コンポーネント

文字化け調査用のコンポーネントを作ると便利です。

import React from 'react';

function CharacterDebugger({ text }) {
  const debugCharacters = (str) => {
    console.log('Original text:', str);
    console.log('Length:', str.length);
    console.log('Character codes:', str.split('').map(c => c.charCodeAt(0)));
    console.log('UTF-8 bytes:', new TextEncoder().encode(str));
  };

  React.useEffect(() => {
    if (text) {
      debugCharacters(text);
    }
  }, [text]);

  return (
    <div style={{ border: '1px solid #ccc', padding: '10px', margin: '10px' }}>
      <h4>文字化けデバッグ</h4>
      <p>表示テキスト: {text}</p>
      <p>文字数: {text ? text.length : 0}</p>
      <small>コンソールで詳細情報を確認してください</small>
    </div>
  );
}

// 使用例
function App() {
  return (
    <div>
      <CharacterDebugger text="こんにちは世界" />
      <CharacterDebugger text="Hello World" />
    </div>
  );
}

このコンポーネントを使うと、文字化けの詳細情報がわかります。

エンコーディング確認関数

プログラムでエンコーディングを確認する関数も作れます。

const checkEncoding = (text) => {
  const encoder = new TextEncoder();
  const decoder = new TextDecoder();
  
  try {
    // UTF-8として処理
    const encoded = encoder.encode(text);
    const decoded = decoder.decode(encoded);
    
    console.log('Original:', text);
    console.log('Encoded bytes:', Array.from(encoded));
    console.log('Decoded:', decoded);
    console.log('Round-trip successful:', decoded === text);
    
    return decoded === text;
  } catch (error) {
    console.error('Encoding check failed:', error);
    return false;
  }
};

// 使用例
const testTexts = [
  'こんにちは',
  'Hello World',
  '日本語テスト',
  '漢字カタカナひらがな'
];

testTexts.forEach(text => {
  console.log(`Testing: "${text}"`);
  checkEncoding(text);
  console.log('---');
});

この関数で、文字が正しくUTF-8として処理されているかわかります。

予防策でもう文字化けしない

最後に、今後文字化けを起こさないための予防策をまとめます。 これらを実践すれば、文字化けとは無縁の開発ができます。

開発環境の統一

チーム開発の場合は、設定を統一することが重要です。

// .editorconfig
root = true

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

[*.md]
trim_trailing_whitespace = false

この設定ファイルをプロジェクトに追加すると、エディタが自動で適切な設定を使ってくれます。

ESLintとPrettierの設定

コードフォーマッターでも文字化けを防げます。

// .prettierrc
{
  "semi": true,
  "trailingComma": "es5",
  "singleQuote": true,
  "tabWidth": 2,
  "useTabs": false
}
// package.json
{
  "scripts": {
    "format": "prettier --write src/**/*.{js,jsx,ts,tsx,json,css,md}",
    "lint": "eslint src/**/*.{js,jsx,ts,tsx}"
  }
}

定期的にフォーマットすることで、エンコーディング問題も防げます。

自動テストの追加

文字化けを検知するテストも書いておきましょう。

import { render, screen } from '@testing-library/react';
import App from './App';

describe('Japanese Text Rendering', () => {
  test('日本語が正しく表示される', () => {
    render(<App />);
    
    // 日本語テキストが正確に表示されるかテスト
    expect(screen.getByText('こんにちは')).toBeInTheDocument();
    expect(screen.getByText('日本語アプリ')).toBeInTheDocument();
  });

  test('APIからの日本語データが正しく表示される', async () => {
    // API モックを日本語データで設定
    const mockData = { message: 'テストメッセージ' };
    
    render(<App />);
    
    // 非同期で日本語データが表示されるかテスト
    expect(await screen.findByText('テストメッセージ')).toBeInTheDocument();
  });
});

このようなテストがあれば、デプロイ前に文字化けを発見できます。

チェックリストの活用

新機能追加時のチェックリストも作っておくと安心です。

文字化けチェックリスト

  • HTMLのcharsetがUTF-8になっている
  • ファイルがUTF-8で保存されている
  • APIリクエストにcharset=utf-8を指定
  • レスポンスヘッダーを確認
  • 日本語フォントが適用されている
  • 開発環境と本番環境で同じ設定
  • 自動テストが通る

このチェックリストを使えば、文字化けを確実に防げます。

まとめ:文字化けはもう怖くない!

Reactでの日本語文字化け対策について、詳しく解説しました。

文字化けの主な原因

  1. HTMLのcharset設定: <meta charset="UTF-8">を確認
  2. ファイルのエンコーディング: UTF-8で保存
  3. APIの設定: リクエスト・レスポンスにcharset指定
  4. フォント設定: 日本語対応フォントを使用
  5. サーバー設定: デプロイ先の設定も確認

解決のポイント

  1. 段階的に確認: HTML→ファイル→API→サーバーの順番
  2. デバッグツール活用: 開発者ツールとカスタム関数
  3. 予防策の実践: 設定統一とテスト自動化
  4. チーム共有: チェックリストで品質維持

今後気をつけること

  • 新機能追加時: 必ずチェックリストで確認
  • デプロイ前: 本番環境での動作テスト
  • 定期確認: エンコーディング設定の見直し

文字化けは最初は複雑に感じるかもしれませんが、原因と対処法を理解すれば必ず解決できます。 今回紹介した方法を使って、快適な日本語Reactアプリを作ってくださいね!

きっと、もう文字化けに悩まされることはありませんよ。

関連記事