폴더 구조 수정과 리팩토링이 조금 남아있지만 이제 네컷지도 프로젝트가 막바지로 향해가고 있다. 기본적인 핵심 기능들은 구현이 완료되었고, 이번에는 FAQ 페이지를 구현하면서 문의할 사항들을 프로젝트 측에 유저가 전달할 수 있도록 이메일 링크를 걸어주는 작업을 하면서 몇가지 헷갈렸던 사항들을 정리하고자 한다. Nextjs의 Link 컴포넌트의 내용과 함께!
Link 컴포넌트
일단 Nextjs의 Link 컴포넌트에 대해서 살펴보자. Nextjs는 pages 폴더내에서 애플리케이션의 라우팅이 구성되고, Nextjs의 Link 컴포넌트는 페이지 전환을 위한 컴포넌트로 클라이언트 측에서 페이지를 전환하기 때문에, 새로고침이 일어나지 않는다. Link 컴포넌트의 대표적인 props는 다음과 같다.
Link 컴포넌트 props
- href : 이동하려고 하는 페이지의 경로를 지정하는 prop으로 일반적으로 파일 시스템의 파일 경로를 따른다.
- replace : 페이지가 전환되었을 때, 기존 페이지의 브라우저 히스토리를 대체할지를 결정한다.
- prefetch : 링크된 페이지의 자원을 사전에 로드할지를 결정한다.
이 외에도 다양한 props가 존재하지만, 모두 다 소개하기에는 공식문서를 참고하는게 더 자세하고 설명이 잘되어있으니 참고하길 바란다.
<a> 태그
Nextjs의 Link 컴포넌트와 다르게 <a> 태그는 페이지 전환시 브라우저가 새로고침된다. Link 컴포넌트와 <a>태그 모두 렌더링 결과는 <a> 태그로 되어있음을 알 수 있지만, 몇가지 중요한 차이점이 존재한다.
Link 컴포넌트와 <a>태그의 차이점
Link 컴포넌트는 Client Side Navigate를 제공하는데, 페이지 이동시에 브라우저가 전체 페이지를 로드하는 대신 페이지의 부분적인 업데이트를 통해 페이지 간 부드러운 전환과 사용자 경험을 제공한다. 다음 예시를 살펴보자.
임의로 백그라운드 컬러를 적용한 뒤 Link 컴포넌트를 통해 페이지를 이동했을 때와, <a> 태그를 이용해서 페이지를 이동했을 때, 결과는 위와 같이 Link 컴포넌트를 통해 페이지를 이동하면 full reload 없이 컴포넌트만 교체되는 것을 볼 수 있다.
추가적으로 Link 컴포넌트의 prefetch 기능을 확인해보기 위해서 배포된 서버를 통해 확인해보면 다음과 같이 Link 컴포넌트를 통해 링크가 걸려있는 페이지들의 js 파일을 prefetch 해오는 것을 알 수있다. 따라서 Link 구성요소가 브라우저의 뷰포트에 보일 때마다 백그라운드에서 Link 컴포넌트를 통해 링크된 페이지에 대한 코드를 자동으로 가져오게 되고, 유저는 즉각적인 페이지 전환을 경험할 수 있는 것이다. 이 때 유의해야할 점은 prefetch를 확인하기 위해서는 개발서버에서는 작동하지 않기 때문에 꼭 배포서버에서 확인하길 바란다.
이메일 주소 링크걸기
FAQ 페이지를 구현하면서 콘텐츠에 애플리케이션 이메일이 포함되어 있기 때문에, 유저가 이메일을 클릭하는 경우 바로 메일을 작성할 수 있도록 구현하고 싶었다. 이메일 주소에 링크를 거는 건 어려운 일이 아니지만, Nextjs를 사용하면서 Link 컴포넌트, <a> 태그 중 어느 방법을 사용해야하는지 고민하면서 위와 같이 Next/Link에 대해 더 공부해보는 시간이 되었다. 결론적으로는 Next/Link는 애플리케이션 내부 라우팅 된 페이지간 이동을 위한 기능이기 때문에, 외부 리소스인 이메일 링크는 <a>태그를 통해 구현하는 것이 좋다고 판단했고, 구현된 코드는 다음과 같다.
...
const FaqModal = ({ isModal, title, content, setIsModal }: ModalProps) => {
const renderContent = () => {
const emailRegex = /[\w.+-]+@[\w-]+\.[\w.-]+/g;
const emailMatch = content.match(emailRegex);
if (emailMatch) {
const emailIndex = content.indexOf(emailMatch[0]);
const emailLength = emailMatch[0].length;
return (
<ModalMessage>
{content.substring(0, emailIndex)}
<a
className="cursor-pointer text-blue-500"
href={`mailto:${emailMatch[0]}`}
>
{emailMatch[0]}
</a>
{content.substring(emailIndex + emailLength)}
</ModalMessage>
);
}
return <ModalMessage>{content}</ModalMessage>;
};
return isModal ? (
<ModalBG>
<div className="p-6">
<ModalTitle>{title}</ModalTitle>
{renderContent()}
</div>
</ModalBG>
) : (
<></>
);
};
...
export default FaqModal;
'개발' 카테고리의 다른 글
promise를 사용한 전역 모달 관리 (feat. contextAPI) (0) | 2024.03.05 |
---|---|
[개발] Nextjs에서 SEO 최적화하기 (0) | 2023.06.02 |
[개발] nextjs에서 모달 관리하기 (feat. recoil) (0) | 2023.05.08 |
[개발] 페이지 접근 제한 구현 (0) | 2023.04.17 |
[React] Debounce 훅 구현하기 (0) | 2023.04.13 |