pathname에 대해 정확히 알고가자
개요
캐시백 쿠폰몰을 구현하면서 페이지별로 뒤로가기 동작을 다르게 처리해야 하는 상황이 있었습니다. 일반 홈페이지에서는 뒤로가기를 누르면 히스토리의 최상단으로 이동하는 것이 자연스러웠지만, 웹뷰 환경에서는 뒤로가기 버튼이나 스와이프 동작 시 다른 방식으로 동작해야 했습니다. 이를 해결하기 위해 pathname을 활용하여 분기 처리를 적용했습니다.
url 구조
프로토콜://host이름:포트번호/경로?쿼리데이터#프레그먼트 url구조는 기본적으로 이렇게 이루어져있어요.
이 때 경로는 웝 서버에 있는특정 파일이나 디렉토리의 위치를 나타내요.
쿼리 문자열은 웹 서버에 추가적인 정보를 전달해주는데, 검색이타 필터링 옵션에서 동적으로 변하는 데이터를 포함해줍니다. 키-값 형태의 데이터에요.
pathname
https://www.example.com/products/category/item.html?id=123
이라는 url에서 pathname은 /products/category/item.html 이 pathname 이에요. 이를 출력하기 위해서는
const pathname = window.location.pathname
해당 코드를 사용하면 pathname을 가져올 수 있어요. 하지만 해당 코드처럼 사용을 하면 url이 변동이 될 때 자동으로 업데이트가 되지 않아, 경로 변경에 반응하여 컴포넌트를 렌더링해야하는 경우에는 적합하지 않아요.
usePathname hook
Next.js 13 버전 이상에서는 url의 pathname을 동적으로 가져오는 데 사용합니다.
"use client"
import { usePathname } from 'next/navigation';
export default function NavLink() {
const pathname = usePathname();
return (
<nav>
<a href="/dashboard" style={{ color: pathname === '/dashboard' ? 'red' : 'blue'}}>
대시보드
</a>
</nav>
)
}
해당 코드와 같이 경로 변경에 대해서 동적으로 반응을 하기 위해서는 usePathname hook을 사용하는 것이 좋습니다.
프로젝트에서는..
프로젝트에서는 뒤로가기 버튼 및 스와이프에 대해서 처리를 해주어야했습니다. 웹뷰 상에서 해당 상태를 인지하기 위해서는 globalThis.fnBackPressed를 활용해 처리해줄 수 있어요.
const pathname = usePathname()
useLayoutEffect(() => {
globalThis.fnBackPressed = () => {
if (window.location.href.slice(window.location.origin.length) !== '/홈') {
if (pathname.startWith('/홈/결제화면')) {
// 쿼리 데이터가 있다면
const urlParams = new URLSearchParams(window.location.search)
if (urlParams.has('home')) {
window.location.replace('/홈')
return
}
}
if (pathname.startWith('/홈/결제화면/결제완료화면') || pathname.startWith('/홈/결제화면/콜백주소')) {
window.location.replace('/홈')
return
}
}
// 만약 홈이면 서비스 종료
setExit(true)
}
}, [pathname])
