웹사이트를 말하게 만들기 (사용자를 겁주지 않게)

발행: (2026년 2월 6일 오후 04:30 GMT+9)
5 min read
원문: Dev.to

Source: Dev.to

당신의 웹사이트가 말하도록 만들기 (사용자를 겁주지 않게) 커버 이미지

소개

솔직히 말해서, 대부분의 웹사이트는 너무 조용합니다. 우리는 빛나는 사각형을 바라보며 1995년처럼 텍스트를 읽으며 살아갑니다. 하지만 브라우저에는 Web Speech API라는 숨겨진 초능력이 있습니다. 그것은 말을 할 수 있습니다. 그리고 2008년의 이상한 자동 재생 비디오 광고를 말하는 것이 아닙니다.

Building a TTS Weather App

오늘은 온도만 보여주는 것이 아니라 분위기를 요약하고 읽어주는 날씨 대시보드를 만들겠습니다.

스택

  • React.js – 컴포넌트 및 상태 관리를 위해.
  • Web Speech API – 특히 window.speechSynthesis.
  • OpenWeatherMap API – 날씨 데이터용 (또는 원하는 다른 날씨 API).

1. “두뇌”: 가져오기 및 요약

우선, 말할 가치가 있는 것이 필요합니다. {"temp": 273.15}와 같은 원시 JSON 응답은 기계에는 좋지만, 사람들은 “춥다, 안에 있어라”와 같은 표현을 선호합니다.

const fetchWeatherSummary = async (city) => {
  const response = await fetch(
    `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=YOUR_API_KEY&units=metric`
  );
  const data = await response.json();

  // A simple summarizer (you could pipe this to an LLM for more “flavour”)
  return `Currently in ${data.name}, it's ${data.main.temp} degrees with ${data.weather[0].description}. My professional advice? ${data.main.temp > 25 ? "Wear a hat." : "Grab a jacket."}`;
};

Source:

2. “Voice” 소개: SpeechSynthesis 만나기

window.speechSynthesis 컨트롤러는 “utterance”(말하고자 하는 내용) 큐를 관리합니다.

useSpeech Hook

음성 엔진을 깔끔한 React Hook으로 감싸 UI 로직을 정리합니다.

import { useState, useEffect } from 'react';

export const useSpeech = () => {
  const [voices, setVoices] = useState([]);

  useEffect(() => {
    const updateVoices = () => setVoices(window.speechSynthesis.getVoices());

    window.speechSynthesis.onvoiceschanged = updateVoices;
    updateVoices();
  }, []);

  const speak = (text: string, voiceName?: string, rate = 1, pitch = 1) => {
    // 현재 진행 중인 대화를 취소
    window.speechSynthesis.cancel();

    const utterance = new SpeechSynthesisUtterance(text);

    // 음성을 선택하거나 기본값으로 대체
    if (voiceName) {
      utterance.voice = voices.find(v => v.name === voiceName) || null;
    }

    utterance.rate = rate;   // 0.1 ~ 10
    utterance.pitch = pitch; // 0 ~ 2

    window.speechSynthesis.speak(utterance);
  };

  return {
    speak,
    voices,
    pause: () => window.speechSynthesis.pause(),
    resume: () => window.speechSynthesis.resume(),
  };
};

Dashboard 컴포넌트

버튼을 통해 데이터를 가져오고 음성으로 읽어주는 모든 기능을 연결합니다.

import React, { useState } from 'react';
import { useSpeech } from './hooks/useSpeech';

const WeatherDashboard = () => {
  const [summary, setSummary] = useState("");
  const { speak, voices } = useSpeech();

  const handleWeatherUpdate = async () => {
    const text = await fetchWeatherSummary("London");
    setSummary(text);
    speak(text, voices[0]?.name, 1.1, 1);
  };

  return (
    <div>
      <h2>Weather Talker</h2>
      <button onClick={handleWeatherUpdate}>Get Audio Summary</button>
      {summary && (
        <p>"{summary}"</p>
      )}
    </div>
  );
};

export default WeatherDashboard;

Speech API를 위한 전문가 팁

  • Voices are lazy – 항상 즉시 로드되지 않습니다. 훅의 onvoiceschanged 이벤트는 voices 배열이 채워지도록 보장합니다.
  • User activation required – 브라우저는 사용자 제스처에 의해 트리거되지 않은 오디오를 차단합니다. speak()를 클릭 핸들러나 유사한 이벤트 안에서 호출하세요.
  • Shortcut library – NPM 패키지 vocalize.ts는 API를 위한 TypeScript‑first 래퍼를 제공합니다. 현재 유지 보수가 적은 상태이지만 핵심 로직은 잘 작동합니다.

왜 귀찮아?

접근성은 명백한 답입니다. 화면 판독기는 훌륭하지만, 특정 “읽어 주세요” 기능은 멀티태스킹을 하는 사용자나 시각 장애가 있는 사람들에게 도움이 될 수 있습니다.

또한 컴퓨터가 당신에게 말을 걸게 만드는 것이 재미있기도 합니다. 다만, 비꼬는 성격을 부여한다면 그 결과에 대비하세요.

행복한 코딩 되세요!

Back to Blog

관련 글

더 보기 »

React에서 List Correctness를 기본값으로 만들기

같은 list boilerplate를 계속 다시 쓰는 것을 그만두세요. 대규모(scale)에서는 반복이 단순히 귀찮은 것이 아니라, correctness 규칙이 약화되고 key bugs와 silent fallbacks가 발생하는 방식입니다.

시간을 절약하고 돈을 벌다

배경: 많은 사람들이 SaaS 도구를 만들기 위해 프로그래밍을 시작합니다. 저는 기본적인 HTML과 JavaScript만 사용해 약 두 시간 만에 약 $10k를 벌어들인 과정을 공유하고 싶습니다.