HDA 시리즈 #7 - SPA 같은 페이지 전환
이번 글에서는 hx-boost를 활용해 페이지 전환 시 깜빡임 없이 SPA처럼 부드럽게 화면을 전환하는 방법을 다룬다.
예제 코드: https://github.com/dev-goraebap/hypermedia-driven-demo/tree/step-07
페이지 추가
이번 단계에서는 "내 정보" 페이지를 추가했다. 이제 할일 목록과 내 정보, 두 페이지 사이를 이동할 수 있다.
<nav>
<ul class="flex gap-2">
<li><a href="/todos">할일</a></li>
<li><a href="/users/me">내 정보</a></li>
</ul>
</nav>
템플릿 레이아웃
페이지가 두 개가 되면서 공통 부분(head, nav, footer 등)을 매번 복사하는 건 비효율적이다. 그래서 공통 부분을 layouts/default.jte로 분리했다.
<%-- layouts/default.jte --%>
@param String title = "App"
@param Content content
<!doctype html>
<html>
<head>...</head>
<body>
<nav>...</nav>
${content}
</body>
</html>
<%-- pages/users/show.jte --%>
@param User user
@template.layouts.default(title = "내 정보", content = @`
<div>
<p>${user.getNickname()}</p>
<p>${user.getEmail()}</p>
</div>
`)
이런 레이아웃 기능은 대부분의 템플릿 엔진이 기본적으로 제공하는 기능이다. 자세한 문법은 각 템플릿 엔진 문서를 참고하면 된다.
MPA의 깜빡임 문제
전통적인 MPA에서 <a> 태그를 클릭하면 브라우저가 전체 페이지를 새로 불러온다. 이 과정에서 화면이 순간적으로 하얗게 변하는 깜빡임 현상이 발생한다.
SPA 프레임워크에 익숙한 사용자에게는 이 깜빡임이 다소 어색하게 느껴질 수 있다. 페이지 전환이 끊기는 느낌을 주기 때문이다.
hx-boost
HTMX의 hx-boost는 이 문제를 한 줄로 해결한다.
<body hx-boost="true">
<nav>
<a href="/todos">할일</a>
<a href="/users/me">내 정보</a>
</nav>
...
</body>
hx-boost="true"를 부모 요소에 설정하면, 하위의 모든 <a> 태그와 <form> 태그가 AJAX 요청으로 동작한다.
- a 태그: GET 요청 + body 교체 + URL pushState
- form 태그: GET/POST 요청 + body 교체 (URL push 안 함)
- JavaScript가 비활성화되면 일반 동작으로 폴백
화면이 깜빡이지 않고 부드럽게 전환된다. 자세한 내용은 HTMX 공식 문서를 참고하자.
수동 방식과 비교
hx-boost 없이 같은 효과를 내려면 각 링크마다 여러 속성을 붙여야 한다.
<a href="/todos"
hx-get="/todos"
hx-target="body"
hx-push-url="true">할일</a>
링크가 많아지면 코드가 지저분해진다. hx-boost는 이걸 한 번에 해결해준다.
정리
- hx-boost: 가장 간단한 SPA 같은 페이지 전환 방법
<a>와<form>모두에 적용됨href를 그대로 유지하므로 SEO, 접근성, JavaScript 비활성화 시 폴백 모두 확보- 부모 요소에 한 번만 설정하면 하위 모든 요소에 적용
다음 글 예고
다음 글에서는 SSR 환경에서 정적 리소스(JavaScript, CSS)를 다루는 방법에 대해 좀 더 깊이 알아볼 예정이다.
이 글은 Hypermedia-Driven Applications 시리즈의 일부입니다.