웹사이트를 말하게 만들기 (사용자를 겁주지 않게)
Source: Dev.to

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

오늘은 온도만 보여주는 것이 아니라 분위기를 요약하고 읽어주는 날씨 대시보드를 만들겠습니다.
스택
- 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 래퍼를 제공합니다. 현재 유지 보수가 적은 상태이지만 핵심 로직은 잘 작동합니다.
왜 귀찮아?
접근성은 명백한 답입니다. 화면 판독기는 훌륭하지만, 특정 “읽어 주세요” 기능은 멀티태스킹을 하는 사용자나 시각 장애가 있는 사람들에게 도움이 될 수 있습니다.
또한 컴퓨터가 당신에게 말을 걸게 만드는 것이 재미있기도 합니다. 다만, 비꼬는 성격을 부여한다면 그 결과에 대비하세요.
행복한 코딩 되세요!