NextJs

[NextJS] Link 태그와 href의 관계

보오 2021. 12. 28. 23:21
  • git에서 더 편하게 보기

https://github.com/uu29/TIL/blob/main/%5BNextJS%5D%20Link%20%E1%84%90%E1%85%A2%E1%84%80%E1%85%B3%E1%84%8B%E1%85%AA%20href%E1%84%8B%E1%85%B4%20%E1%84%80%E1%85%AA%E1%86%AB%E1%84%80%E1%85%A8.md

 

GitHub - uu29/TIL

Contribute to uu29/TIL development by creating an account on GitHub.

github.com


next.js에서 Link는 페이지 이동을 위해 꼭 써야 하는 컴포넌트다.

일반적으로 바닐라 자바스크립트에서는 <a> 태그로 쓰지만, next에서는 Link라는 컴포넌트를 제공한다.

Link 컴포넌트에 관한 자세한 내용은 공식 문서를 참고해보자. (https://nextjs.org/docs/api-reference/next/link)

Link 태그를 쓸 때 아주 간단하지만 중요한 것이 바로 href 속성이다.

 

다음의 두가지를 새겨두자.

 

1. 일반적으로 <Link> 태그 안에 텍스트만 넣어도 <a> 태그가 자동으로 생성된다.

아래와 같이 다이나믹 라우팅을 활용한 간단한 Link 태그가 있다고 했을 때,

<Link href={{ pathname: 'post', query: { id: post_id } }} passHref>
    jlory 블로그 입니다.
</Link>

실제 렌더링된 html 마크업은 이렇게 나온다.

<a> 태그 없이 next.link 아래 string만 채워줬는데도 자동으로 <a> 태그가 생성됨을 알 수 있다.

그렇다면 Link 태그 하위로 커스텀 컴포넌트를 넣으면 next.js에서 어떻게 받아들일까?

 

 

2. <Link>의 자식으로 커스텀 컴포넌트 - ex) styled component - 을 사용할 때 꼭 passHref 속성을 써주자.

Link의 스타일링을 위해 css-in-js로 styled component나 emotion을 많이 쓸 것이다.

이때 꼭 설정해줘야 하는 것이 passHref다.

passHref는 next Link에서 하위 컴포넌트로 href 속성을 전달해주는 역할을 한다.

passHref가 없을 때, 있을 때를 비교해보자.

 

  • passHref 없을 때
<Link href={{ pathname: "post", query: { id: post_id } }}>
    <StyledA>jlory 블로그입니다.</StyledA>
</Link>

 

<Link> 태그 하위로 StyledA라는 스타일드 컴포넌트를 전달했더니 마크업은 제대로 나오나, a 태그의 href가 빠져있다.

클릭해보면 잘 이동하긴 한다. 그러나 이렇게 되었을 때 몇가지 치명적인 점이 생겨난다.

 


Q. a 태그에 href가 빠지면 무슨 일이 발생하나요?

 

(1) UX(사용자 경험)에 좋지 않아요.

 

우선 해당 링크의 Shift + Click | Ctrl + Click 이 안된다. 새 창(또는 새 탭)으로 보기가 안된다. 이건 브라우저의 특징인 것 같은데, 보통 쉬프트나 컨트롤과 같이 누르면 새 창 또는 새 탭에서 링크를 열 수 있다. 그러나 href가 빠진 a 태그는 더이상 anchor text의 역할을 하지 않기 때문에 이동(라우팅)은 되지만, 새 창(탭)에서 열리지 않는다. 웹에서 링크를 마주쳤을 때 현재 탭에서 여는 유저라면 상관없겠지만, 나같이 항상 새 탭으로 열어야 하는 유저라면 사용자 경험이 좋을 수가 없다.

 

(2) SEO에 치명적이에요.

 

구글(을 포함한 검색엔진)이 사이트를 색인(인덱싱)할 때 새로운 페이지가 있는지 확인하는 두 가지 방법이 있는데, 하나는 사이트 맵(sitemap.xml)으로 하는 법, 나머지 하나는 페이지 내 모든 <a> 태그를 찾아 방문하는 방법이다. 이 때, 검색엔진은 <a> 태그의 href 속성을 읽어 페이지 콘텐츠를 인덱싱 한다.

따라서 href가 없는 링크는 (인덱싱이 필요한 페이지라면) 검색엔진이 추적할 수 없으니 SEO에 매우 안좋다고 할 수 있다.

 

 

구글 검색센터에서도 이렇게 명시하고 있다.

 

(그리고 애초에 typescript를 사용한다면 이렇게 경고가 나온다.)

passHref is missing. See https://nextjs.org/docs/messages/link-passhref

passHref가 이렇게나 중요한 것이었다니!

이제 passHref가 있을 때 어떻게 되는지 직접 확인해보자.

 

  • passHref 있을 때
<Link href={{ pathname: "post", query: { id: post_id } }} passHref>
    <StyledA>jlory 블로그입니다.</StyledA>
</Link>

깔끔하게 <a> 태그에 href 속성이 생겼다.

웹표준을 지키면서, 시맨틱 마크업으로 링크를 구현하고 싶다면 네이버나 구글 등 대형 검색엔진 사이트를 참고해보자.

 

3. (보너스) next.js Link 태그의 prefetch 기능

Next.js의 <Link/> 태그의 잘 알려지지 않은 기능 중 하나가 바로 prefetch다. prefetch는 말그대로 "미리 받아온다"는 뜻인데, next.js에서 Link에 사용한 href의 주소를 미리 읽어와서 해당 페이지 리소스를 미리 받아오는 것이다. 이 때, 페이지 내 모든 Link 데이터가 아닌뷰포트 내의 Link 태그 데이터만 미리 받아온다. 뷰포트는 유저의 브라우저로 현재 보이는 화면으로, 스크롤하지 않고 보이는 범위라고 보면 된다.

 

여기서 말하는 페이지 리소스는 Next.js의 자동 코드스플리팅 기능에 의해 쪼개진 각 페이지 자바스크립트 번들 파일을 말한다. 예를 들어 내가 A라는 페이지를 보고 있고, 현재 뷰포트 범위 내 B페이지로 연결되는 <Link/> 태그가 있다면 넥스트에서 미리 B페이지 로딩에 필요한 번들파일을 미리 다운로드 받아놨다는 뜻이다.

 

그렇다면 왜 지금 필요하지도 않은 페이지 소스를 미리 가져오느냐? 당연히 더 빠른 페이지 전환을 위해서다. 유저가 언제 Link를 누를지 모르기에, 최소한 유저가 보이는 화면 안에 있는 Link들이 가리키는 페이지에 대한 데이터는 미리 가지고 있다가 바로 보여주자는 깊은 뜻이다.

 

그런데 만약 미리 페이지 소스를 받아올 필요가 없다면? 굳이 그러고 싶지 않다면?

넥스트는 다 계획이 있다. Link의 기본값으로 prefetch는 true지만, false로 지정하여 이를 끌 수도 있다. <Link prefetch={false}/> 라고 지정하면 페이지 데이터를 미리 가져오지 않게 된다. 그러나 false로 설정해도, 유저가 Link 위에 마우스를 올리면(hover) 해당 링크가 가리키는 페이지는 자동으로 prefetch 된다.

 

추가로, 이 prefetch는 production 모드에서만 실행된다. 따라서 개발모드로는 확인할 수 없고 production 모드로 돌린 후 네트워크 탭을 통해 확인이 가능하다.

 

정리하면

- next.js의 Link 태그는 뷰포트 내에서 기본적으로 Link가 가리키는 페이지 데이터를 미리 가져온다.
- 이 기능은 prefetch=false 설정을 통해 끌 수 있지만, 그래도 마우스 오버 시에는 작동한다.
- production 모드에서만 작동한다. (고로 next.js는 production 모드에서 더 빠르다.)

 

더 자세한 정보는 next.js 공식문서 - Link를 참고하자.

 

 

 

 

 

 

- 출처 & 참고

https://crong-dev.tistory.com/50

https://stackoverflow.com/questions/10510191/valid-to-use-a-anchor-tag-without-href-attribute

https://moz.com/learn/seo/anchor-text

https://developers.google.com/search/docs/beginner/seo-starter-guide