3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HTMXとGemini APIを用いて簡単なチャットアプリを作ってみた

Last updated at Posted at 2024-02-24

はじめに

57歳で製造業からWeb開発企業に転職して、やっと2年目に突入したピータンと申します。

最近、個人的にHTMXが気になっています。そこで、これとGoogleの生成AIであるGeminiAPIを使って、簡単なチャットアプリを作ってみたので紹介します。

image

HTMXとは?

  • JavaScript ライジングスター 2023のフロントエンドフレームワーク部門で、王者のReactに次ぐ2位となった注目の技術です
  • HTMXは、Reactのように非同期通信による動的なサイト更新などを実現する軽量のソリューションです
  • hx-なんちゃらというカスタム属性を使用することでHTMLを拡張し、JavaScriptコードを書かずにAPIを使い、ページの一部更新ができます
  • HTMXは、Reactに比べて学習が圧倒的に簡単で、その日から使えました
  • Web制作でのコンタクトフォームの実装に便利です
  • シンプルなインタラクティブ機能を備え、特に高度な機能を備えないサイトを構築する場合は、HTMXの方がReactより優れたソリューションとなる可能性があります
    • 状態管理が必要で、複雑な機能を提供し、再利用可能なコンポーネントが必要なWebアプリケーションを作成する場合は、Reactがより適切とは思います

Geminiとは?

  • 2023年12月に発表されたGoogleの生成AIモデルです
  • 以前はBardと呼ばれていました

実装方法

詳細は、GitHubをご覧ください。

フロントエンド

HTML, CSS, 少量のJavaScriptとHTMXを使用しました。少量のJavaScriptは、以下のために使っています。これが不要なら、フロントエンドは完全にJavaScriptなしとなるのですが。

  • [送信]ボタンをクリックしたあとのテキストエリアのクリア
  • [送信]ボタンをクリックしたあとのページ下部への自動スクロール
  • テキストエリアでEnterキーを入力したら自動で高さを増やす

index.htmlは次になります。

index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ジェミニ君</title>
    <link rel="stylesheet" href="/style.css" />
    <link rel="icon" href="/favicon.ico" type="image/x-icon" />
    <script src="https://unpkg.com/htmx.org@1.9.10"></script>
    <script src="textarea.js"></script>
    <body>
      <div class="container">
        <h1>HTMXとGeminiを用いたシンプルチャット</h1>
        <div id="chat-messages"></div>
        <form
          hx-post="/api/generate"
          hx-target="#chat-messages"
          hx-swap="beforeend "
        >
          <textarea
            id="message-input"
            placeholder="WEFについて教えてください。"
            type="text"
            name="message"
            required
            rows="1"
          ></textarea>
          <button name="submit" type="submit" id="submit-button">送信</button>
          <div class="htmx-indicator loader"></div>
        </form>
        <p class="copyright">
          Powered by
          <a
            href="https://over40web.club"
            target="_blank"
            title="Over 40 Web Club"
            >Over 40 Web Club</a
          >
        </p>
      </div>
    </body>
    <script src="chat-ui-updates.js"></script>
  </head>
</html>
  • <form>タグのカスタム属性(hx-***)でAPIと通信してチャットを表示する機能を実現しています
  • <div class="htmx-indicator loader"></div>のようにhtmx-indicatorというクラスを追加するだけで生成AIが考え中のときのローディングアニメーションを実現しています
  • <script>タグで2つのJavaScriptファイルを読み込んでいます。そちらはGitHubをご覧ください

バックエンド

  • Node.jsのフレームワークの express.jsを使用しています。Googleのチュートリアルには、Node.jsの他、PythonやGo, Swiftなどからの利用方法が解説されています
  • バックエンドからGeminiのAPIを呼び出しています
    • 「◯◯だよー。」と言わせるようにしています
    • マルチターンの会話(チャットなど)を構築するために、gemini-pro モデルを使用し、startChat() を呼び出してチャットを初期化しています
    • 次に、sendMessage() を使用して新しいユーザー メッセージを送信するようにしています
  • 詳細は、GitHubをご覧ください

デプロイ

  • こちらはVercelにスタンドアロンのExpress.jsアプリとしてデプロイしました
  • これを実現するために、APIのコードはapiフォルダ以下に配置し、ルートにvercel.jsonを配置します
vercel.json
{
  "rewrites": [
    {
      "source": "/api/(.*)",
      "destination": "/api"
    }
  ]
}

おわりに

これを作る前に、コンタクトフォームも作ってみました。HTMXを使うと、APIとやり取りをして、ページを更新するといったことが、JavaScriptを書かずに非常に簡潔におこなえます。今回の例では多少JavaScriptが必要になりました。APIはHTMLを返却する必要があることから、基本自作にはなってしまいます。

Geminiも最初、model.generateContentというメソッドを使ったときには、次のような応答となりましたが、今回の実装方法では可愛げのある結果が得られました。

image.png

今回、自動スクロールの実装がうまくいかず、タイマーを使う苦し紛れの実装となりました。フィードバッグなどありましたら、お気軽にお願いいたします。

関連記事

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?