History API는 브라우저의 페이지 이동(새로고침) 없이 URL을 변경하고, 브라우저의 세션 기록(session history)을 조작할 수 있게 해주는 자바스크립트 API이다.
이 API는 React, Vue, Angular 등으로 만드는 SPA(Single Page Application)의 핵심 기술이라고도 할 수 있는데 왜일까?
전통적인 웹사이트에서는 다른 페이지로 가려면 링크를 클릭하고, 브라우저는 서버에 새 페이지를 요청한 뒤 완전히 새로고침한다.
그러나 SPA는 처음에 단 하나의 페이지만 불러온 뒤, 페이지 이동 없이 자바스크립트가 동적으로 내용물만 바꿔주는 방식이다. 여기서 문제가 발생한다.
History API는 이러한 문제들을 해결하기 위해 등장했다. 페이지를 실제로 새로고침하지 않으면서 URL을 바꿔주고, 브라우저의 뒤로/앞으로 가기 버튼에 반응할 수 있게 해준다.
페이지를 새로고침하지 않고 브라우저 히스토리 스택에 새로운 상태를 추가한다.
URL을 바꾸는 가장 핵심적인 기능
// 사용자가 'About' 메뉴를 클릭했다고 가정
const state = { page: 'about' };
const title = 'About Us';
const url = '/about';
history.pushState(state, title, url);
// 이 코드가 실행되면, 페이지 새로고침 없이 주소창의 URL이 'www.example.com/about'으로 바뀐다.
pushState와 비슷하지만, 히스토리 스택에 새 항목을 추가하는 대신 현재 항목을 수정한다. 뒤로 가기를 해도 이전 기록이 남지 않음.
(URL의 쿼리 파라미터를 바꿀 때 유용하다)
사용자가 브라우저의 뒤로 가기, 앞으로 가기 버튼을 누르거나, 자바스크립트로 history.back(), history.forward() 등을 호출했을 때 window 객체에서 발생하는 이벤트이다.
이 이벤트를 감지(listen)하여, pushState로 저장했던 state 객체를 꺼내 해당 상태에 맞는 화면을 다시 그려주는 로직을 실행한다.
window.addEventListener('popstate', (event) => {
console.log(event.state); // pushState로 저장했던 state 객체 (예: { page: 'about' })
// event.state 객체를 보고, 그에 맞는 페이지 내용을 동적으로 렌더링
if (event.state && event.state.page === 'about') {
renderAboutPage();
} else {
renderHomePage();
}
});
React Router, Vue Router 같은 모든 최신 라우팅 라이브러리들은 내부적으로 이 History API를 기반으로 만들어져 있다.