OpenAI APIとNext.js(React)でGPTの回答をマークダウン(Markdown)で取得する

2025/06/02 (月) - 09:00 JavaScript

Next.js(AppRouter)とOpenAI APIを利用して、テキストフォームから入力した質問の回答をマークダウン形式で取得し、HTMLで表示するサンプル。Next.jsやReactでマークダウンを扱う場合はreact-markdownのモジュールを使うと便利です。

$ npm i react-markdown

予めモジュールを入れておきましょう。あとはOpenAI PlatformでAPIキーの発行とクレジットの確保も忘れずに。今回は以下の環境下で実装しています。

  • Next.js 14.2.x (AppRouter)
  • React 18.3.x
  • react-markdown 1.9.x

取得したAPIキーは.envで設定します。

API_KEY=sk-********************

フロント部分のpage.tsxで質問フォームと表示エリアを実装。ポイントは回答部分をReactMarkdownでマークアップすることです。これによりマークダウン形式のテキストがHTMLに変換されて表示されます。

'use client';
import { useState } from 'react';
import ReactMarkdown from 'react-markdown';
export default function Home() {
 const [prompt, setPrompt] = useState('');
 const [response, setResponse] = useState('');
 const [loading, setLoading] = useState(false);
 const handleSubmit = async (e: React.FormEvent) => {
  e.preventDefault();
  setLoading(true);
  const res = await fetch('/api/chatgpt', {
   method: "POST",
   headers: {
    'Content-Type': 'application/json',
   },
   body: JSON.stringify({ prompt })
  });
  const data = await res.json();
  setResponse(data.text);
  setLoading(false);
 };
 return (
  <main>
   <form onSubmit={handleSubmit}>
    <textarea value={prompt} onChange={(e) => setPrompt(e.target.value)} placeholder="質問を入力してください"></textarea>
    <button type="submit" disabled={loading}>質問する</button>
   </form>
   {loading && <p>生成中…</p>}
   {response && (
    <div>
     <ReactMarkdown>{response}</ReactMarkdown>
    </div>
   )}
  </main>
 );
}

API部分の実装。Next.jsのAPI Routesを利用して実装しました。srcディレクトリに/api/chatgpt/route.tsを配置し実装します。フロントからリクエストされたされたプロンプトをPOSTで処理します。

import { NextResponse } from 'next/server';
export async function POST(req: Request) {
 try {
  const { prompt } = await req.json();
  const response = await fetch('https://api.openai.com/v1/chat/completions', {
   method: 'POST',
   headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${process.env.API_KEY}`,
   },
   body: JSON.stringify({
    model: 'gpt-4o-mini', //モデルを選択
    messages: [
     { role: 'user', content: prompt }
    ],
   }),
  });
  const data = await response.json();
  const text = data.choices[0].message?.content?.trim() || '';
  return NextResponse.json({ text });
 } catch (error) {
  console.error(API エラー:', error);
  return NextResponse.json({ error: '生成に失敗しました' }, { status: 500 });
 }
}

実際に実装し質問を実行した際の表示例。蔦屋重三郎の生い立ちについて質問し正常にHTMLフォーマットで回答文が表示されています。

回答結果

フロントのCSS側はマークダウンで再現できる一般的なHTML要素(見出し、リスト、table等)が綺麗に見やすく表示されるように整えておく必要があります。

おしまい

タグ:

記事をシェアする

  • facebookでシェアする
  • twitter(X)でシェアする
  • LINEでシェアする
  • はてなブックマークでシェアする
  • Threadsでシェアする
  • Pocketでシェアする
  • Pinterestでシェアする

おすすめ記事

トラックバック & ピンバック

この記事へのトラックバックURI
https://weblog.walk-life.me/nextjs_markdown_gpt/trackback/

コメント

コメントは下記からどうぞ

ページの先頭へ