콘텐츠로 건너뛰기

History API를 활용한 브라우저 세션 기록 조작

  • 테크

SPA(Single Page Application)는 웹 애플리케이션 개발에서 사용자 경험을 극대화하기 위해 널리 사용되는 방식입니다. 하지만, 단일 페이지에서 동적으로 콘텐츠를 변경하는 특성 상, 브라우저의 기본 탐색 기능(뒤로 가기, 앞으로 가기 등)을 제대로 지원하지 않으면 사용자가 혼란을 느낄 수 있습니다.

이를 해결하기 위한 필수 도구가 바로 History API입니다. History API를 활용하면 브라우저의 세션 기록을 조작해서 사용자 경험을 개선할 수 있습니다.

이번 포스팅에서는 History API의 주요 이벤트와 메소드를 알아보도록 하겠습니다.

History API 란

History API는 브라우저의 세션 기록(History Stack)에 접근하고 조작할 수 있는 JavaScript 인터페이스입니다. 이를 통해 페이지를 새로 고침하지 않고도 URL과 상태를 동적으로 관리할 수 있습니다.

주요 기능

  • 세션 기록 관리: URL을 변경하거나 세션 상태를 추가할 수 있습니다.
  • 탐색 이벤트 처리: 사용자가 “뒤로 가기” 또는 “앞으로 가기” 버튼을 클릭했을 때 이를 감지하고 처리할 수 있습니다.

주요 메소드

  • history.pushState(state, title, url): 새 상태를 스택에 추가합니다.
  • history.replaceState(state, title, url): 현재 상태를 교체합니다.
  • history.back(), history.forward(), history.go(n): 탐색 기록을 기반으로 페이지를 이동합니다.

주요 이벤트

  • popstate 이벤트: 사용자가 브라우저의 뒤로 가기 또는 앞으로 가기 버튼을 클릭하거나 history.go() 메서드로 탐색할 때 발생합니다. popstate 이벤트를 통해 뒤로 가기 막기와 같은 페이지 이동 시의 동작을 정의할 수 있습니다.
  • 예시:
window.addEventListener('popstate', (event) => {
    // beforeunload 대신 popstate 이벤트에 리스너를 추가했다.
    console.log('popstate:', event.state);
});

History API를 이용해 직접 구현해보기

History API를 통해 URL을 변경하고 DOM 업데이트를 동기화 하는 과정을 예제를 통해 구현해보겠습니다.
버튼 클릭 시 새로고침 없이도 URL이 변화하고, popstate 이벤트 발생 시 이전 상태로 복원하는 과정을 알아보겠습니다.

  • HTML 구조
<h1>History API로 이미지 전환</h1>
  <p>버튼을 클릭하면 History API를 사용해 URL이 변경되고, 페이지 콘텐츠가 그에 따라 업데이트됩니다.</p>
  <p>현재 URL: <span id="current-url"></span></p>
  <div>
    <button id="home">처음으로</button>
    <button id="image1">이미지 1</button>
    <button id="image2">이미지 2</button>
    <button id="image3">이미지 3</button>
  </div>
  <div id="home-message">
    <p>이미지 버튼을 눌러주세요.</p>
  </div>
  <div id="image-container">
    <img id="pipeline" src="https://bizspring.co.kr/company/img/en-cases-01.png" alt="Image 1">
    <img id="datacenter" src="https://bizspring.co.kr/company/img/resources2310-2.png" alt="Image 2">
    <img id="database" src="https://bizspring.co.kr/company/img/en-cases-05.png" alt="Image 3">
  </div>
  • 자바스크립트 주요 부분
const url = new URL(window.location.href);
const baseUrl = url.origin + url.pathname; 

쿼리 파라미터를 제외한 현재 URL을 추출합니다.
“처음으로” 버튼을 눌렀을 때 히스토리 기록에 base url을 넣을 수 있습니다.

function showImage(imageId, shouldPushState = true) {
  images.forEach(img => img.classList.remove('active'));
  homeMessage.classList.remove('active');

  if (imageId) {
    const targetImg = document.getElementById(imageId);
    if (targetImg) {
      targetImg.classList.add('active');
      if (shouldPushState) {
        history.pushState({ image: imageId }, '', `?image=${imageId}`);
      }
    } else {
      showHome();
    }
  } else {
    showHome();
  }
  updateUrl();
}

특정 이미지를 활성화하고, history.pushState로 주소와 state를 업데이트합니다. shouldPushState가 false일 경우에는 히스토리 기록을 쌓지 않습니다

function showHome() {
  images.forEach(img => img.classList.remove('active'));
  homeMessage.classList.add('active');
  history.pushState({}, '', baseUrl);
  updateUrl();
}

이미지를 모두 숨기고 안내 문구를 보여주며, pushState로 홈 상태를 스택에 등록합니다.

window.addEventListener('popstate', (event) => {
  if (event.state && event.state.image) {
    showImage(event.state.image, false);
  } else {
    showHome();
  }
});

사용자가 뒤로 가기, 앞으로 가기 버튼을 누를 때 발생합니다. event.state에 이미지 정보가 있으면 해당 이미지를 다시 보여주고, 없으면 홈 화면으로 돌아갑니다.

const params = new URLSearchParams(window.location.search);
if (params.has('image')) {
  const imageId = params.get('image');
  history.replaceState({ image: imageId }, '', `?image=${imageId}`);
  showImage(imageId, false);
} else {
  showHome();
}

페이지를 처음 로드했을 때 ‘image’ 파라미터가 있으면 replaceState로 현재 기록을 덮어쓰고, 해당 이미지를 표시합니다.

History API로 이미지 전환

History API를 이용한 예시

버튼을 클릭하면 History API를 사용해 URL이 변경되고, 페이지 콘텐츠가 그에 따라 업데이트됩니다.

현재 URL:

이미지 버튼을 눌러주세요.

Image 1 Image 2 Image 3

이번 포스팅에서는 History API에 대해 알아보았습니다. History API를 사용하면 브라우저의 세션 기록(History Stack)에 접근하고 조작할 수 있습니다. 이를 통해 페이지를 새로 고침하지 않고도 URL과 상태를 동적으로 관리할 수 있습니다.

Ref.
History API MDN 문서
History API MDN 데모

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다