HTML/CSS/TypeScript로 AI 채팅 화면 만들기(2) - (무료)제미나이 API 붙이기

지현·2026년 4월 27일
post-thumbnail

JS로 Gemini API 붙여보기(무료)

제미나이 API는 무료로 사용할 수 있다. 이번 포스팅에서는 별도의 프레임워크 없이 JavaScript로 채팅 화면에 Gemini API를 연동하는 방법을 정리해본다.


1. API 키 발급

Google AI Studio 에 접속해서 API 키를 발급받는다.

👉 https://aistudio.google.com/

접속 후 로그인 → "API 키 만들기" 클릭

API 키 만들기


2. API 키 생성 확인

생성된 키를 복사해둔다.

API 키 생성

⚠️ 주의: API 키는 코드에 직접 하드코딩하지 말자.
config.js 파일을 따로 만들어서 관리하고, .gitignore에 추가하는 것을 권장한다.

// config.js (git과 블로그에는 올리지 않음)
const CONFIG = {
  API_KEY: "여기에_본인_API_KEY_입력"
};
// main.js
const API_KEY = CONFIG.API_KEY;

3. API 호출 코드

아래는 채팅 화면에 Gemini API를 연동한 전체 코드다.

async function ask() {
  const inputElement = document.getElementById("questionInput");
  const prompt = inputElement.value;

  // 빈 입력 체크
  if (!prompt || prompt.trim() === "") {
    document.getElementById("output").innerText = "질문을 입력해주세요.";
    return;
  }

  // 입력창 바로 초기화
  inputElement.value = "";

  // [1단계] 화면에 질문과 "...(생각 중)" 상태를 먼저 표시
  const chatGrid = document.getElementById("chatMessagesGrid");
  chatGrid.innerHTML = `
    <article class='message-card active' role=listitem>
      <div class='message-card-user'>${prompt}</div>
      <div class='message-card-bot'>
        <div class="bot-logo">
          👩‍💻 Assistant AI
        </div>
        <div class="bot-answer thinking">...(생각 중)</div>
      </div>
    </article>`;

  try {
    // [2단계] Gemini API 호출
    const res = await fetch(
      `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent?key=${API_KEY}`,
      {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          contents: [{ parts: [{ text: prompt }] }]
        })
      }
    );

    if (!res.ok) throw new Error("API 호출 실패");

    const data = await res.json();
    const text =
      data.candidates?.[0]?.content?.parts?.[0]?.text ??
      "응답을 가져올 수 없습니다.";

    // [3단계] 자연스러운 UX를 위해 1.5초 딜레이
    await new Promise(resolve => setTimeout(resolve, 1500));

    // [4단계] "...(생각 중)"을 실제 답변으로 교체
    const botAnswerDiv = chatGrid.querySelector('.bot-answer');
    if (botAnswerDiv) {
      botAnswerDiv.classList.remove('thinking');
      botAnswerDiv.innerText = text;
    }

  } catch (err) {
    console.error("에러 발생:", err);
    const botAnswerDiv = chatGrid.querySelector('.bot-answer');
    if (botAnswerDiv) botAnswerDiv.innerText = "오류가 발생했습니다.";
  }
}

window.ask = ask;

4. 작동 결과

질문을 입력하면 ...(생각 중) 상태가 먼저 표시되고,

응답이 오면 실제 답변으로 교체된다.


작동 원리

1. 질문 입력
   ↓
2. 화면에 질문 + "..." (로딩 상태) 즉시 표시
   ↓
3. Gemini API에 POST 요청
   ↓
4. 응답 수신 후 "..."을 실제 답변으로 교체

응답을 받아오는 경로는 다음과 같다.

const text =
      data.candidates?.[0]?.content?.parts?.[0]?.text ??
      "응답을 가져올 수 없습니다.";

Gemini API는 응답을 candidates 배열 형태로 반환하기 때문에, 옵셔널 체이닝(?.)으로 안전하게 접근한다.


현재 한계 및 개선 포인트

항목현재 상태개선 방향
대화 기록❌ 저장 안 됨 (매 질문마다 리셋)이전 메시지를 contents 배열에 누적해서 전달
마크다운 렌더링❌ 텍스트 그대로 출력marked.js 등의 라이브러리로 렌더링
스트리밍❌ 응답을 한 번에 받아옴streamGenerateContent 엔드포인트 + ReadableStream으로 처리
API 키 보안⚠️ 브라우저에서 노출됨실서비스에서는 백엔드 서버를 통해 호출

현재는 응답이 완전히 생성된 후에 한 번에 화면에 출력된다. 스트리밍을 적용하면 ChatGPT처럼 글자가 순차적으로 타이핑되는 효과를 구현할 수 있다


마무리

별도의 프레임워크나 백엔드 서버 없이도 Gemini API를 빠르게 연동할 수 있었다.
다음 단계로는 대화 기록 누적, 마크다운 렌더링, 그리고 스트리밍 방식으로의 전환을 시도해볼 예정이다.

0개의 댓글