NextJS API: next/link

hwisaac·2023년 3월 13일
0

NextJS API(page router)

목록 보기
7/10

https://velog.io/@hwisaac/NextJS-Routing-intro 를 먼저 확인하세요

next/link로 클라이언트 측에서 페이지 이동을 할 수 있습니다.

다음과 같은 파일이 있는 페이지 디렉토리를 고려해보세요.

  • pages/index.js
  • pages/about.js
  • pages/blog/[slug].js

이러한 페이지로 링크할 수 있습니다.

import Link from 'next/link'

function Home() {
  return (
    <ul>
      <li>
        <Link href="/">Home</Link>
      </li>
      <li>
        <Link href="/about">About Us</Link>
      </li>
      <li>
        <Link href="/blog/hello-world">Blog Post</Link>
      </li>
    </ul>
  )
}

export default Home

Link는 다음과 같은 프롭을 받습니다.

  • href - 이동할 경로 또는 URL입니다. 이것은 유일한 필수 프롭입니다. 객체일 수도 있습니다. 여기서 예제를 확인하세요.
  • as - 브라우저 URL 표시줄에 표시될 경로에 대한 선택적 장식자입니다. Next.js 9.5.3 이전에는 동적 경로에 사용되었습니다. 이전 문서를 확인하여 작동 방식을 확인하세요. 참고: 이 경로가 href에서 제공한 경로와 다르면 이전 href/as 동작이 이전 문서에 표시된대로 사용됩니다.
  • legacyBehavior - child<a>여야 하는 동작을 변경합니다. 기본값은 false입니다.
  • passHref - Linkhref 프로퍼티를 자식에게 보내도록 강제합니다. 기본값은 false입니다.
  • prefetch - 백그라운드에서 페이지를 프리페치합니다. 기본값은 true입니다. (초기로드시 뷰포트 안에 있거나 스크롤로 나중에 화면에 나타나는) 모든 <Link /> 는 프리페치됩니다. prefetch를 사용하지 않으려면 prefetch={false}를 전달하면 됩니다. prefetchfalse로 설정되면 hover를 통해 프리페치가 이루어집니다. 정적 생성을 사용하는 페이지는 더 빠른 페이지 전환을 위해 데이터의 JSON 파일을 프리페치합니다. 프리페치는 프로덕션 환경에서만 활성화됩니다.
  • replace - 스택에 새 URL을 추가하는 대신 현재 히스토리 상태를 바꿉니다. 기본값은 false입니다.
  • scroll - 이동 후 페이지 상단으로 스크롤합니다. 기본값은 true입니다.
  • shallow - getStaticProps, getServerSideProps 또는 getInitialProps를 다시 실행하지 않고 현재 페이지의 경로를 업데이트합니다. 기본값은 false입니다.
  • locale - 활성 로캘은 자동으로 앞에 추가됩니다. locale은 다른 로캘을 제공할 수 있습니다. false로 설정하면 기본 동작으로 로캘을 href에 포함해야 합니다.

참고: legacyBehaviortrue로 설정되어 있지 않으면, className, onClick 등의 모든 앵커 태그 속성이 next/link에 전달될 수 있습니다.

동적 세그먼트가 있는 경우

동적 라우트, 캐치 올 라우트를 포함한 동적 세그먼트가 있는 경우 링크를 생성할 필요가 없습니다. Next.js 9.5.3부터는 이러한 경우에 대해 아무것도 하지 않아도 됩니다(이전 버전의 경우 이전 문서를 확인하십시오). 그러나 링크를 생성하기 위해 보간(interpolation) 또는 URL 객체를 사용하는 것이 매우 일반적이고 편리할 수 있습니다.

예를 들어, 동적 라우트 pages/blog/[slug].js는 다음과 같은 링크와 일치합니다:

import Link from 'next/link'

function Posts({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>
          <Link href={`/blog/${encodeURIComponent(post.slug)}`}>
            {post.title}
          </Link>
        </li>
      ))}
    </ul>
  )
}

export default Posts

만약 자식이 <a> 태그인 경우

import Link from 'next/link'

function Legacy() {
  return (
    <Link href="/about" legacyBehavior>
      <a>About Us</a>
    </Link>
  )
}

export default Legacy

만약 자식이 <a> 태그를 래핑하는 사용자 정의 컴포넌트인 경우
자식이 <a> 태그를 래핑하는 사용자 정의 컴포넌트인 경우 LinkpassHref를 추가해야 합니다. 이는 styled-components와 같은 라이브러리를 사용하는 경우 필요합니다. 이렇게 하지 않으면 <a> 태그에 href 속성이 없어서 사이트의 접근성(accessibility)이 저하되고 SEO에 영향을 줄 수 있습니다. ESLint를 사용하는 경우, next/link-passhref라는 내장 규칙이 올바른 passHref 사용을 보장합니다.

import Link from 'next/link'
import styled from 'styled-components'

// 이렇게 하면 <a> 태그를 래핑하는 사용자 정의 컴포넌트가 생성됩니다.
const RedLink = styled.a`
  color: red;
`

function NavLink({ href, name }) {
  return (
    <Link href={href} passHref legacyBehavior>
      <RedLink>{name}</RedLink>
    </Link>
  )
}

export default NavLink

emotionJSX pragma 기능(@jsx jsx)을 사용하는 경우, 직접 <a>태그를 사용하는 경우에도 passHref를 사용해야 합니다.

컴포넌트는 onClick 속성을 지원하여 탐색을 올바르게 트리거해야 합니다.

자식이 함수형 컴포넌트인 경우

Link의 자식이 함수형 컴포넌트인 경우, passHreflegacyBehavior를 사용하는 것 외에도 React.forwardRef로 컴포넌트를 래핑해야 합니다:

import Link from 'next/link'

// `onClick`, `href`, and `ref` need to be passed to the DOM element
// for proper handling
const MyButton = React.forwardRef(({ onClick, href }, ref) => {
  return (
    <a href={href} onClick={onClick} ref={ref}>
      Click Me
    </a>
  )
})

function Home() {
  return (
    <Link href="/about" passHref legacyBehavior>
      <MyButton />
    </Link>
  )
}

export default Home

URL 객체로

Link는 URL 객체를 받아들이고 자동으로 URL 문자열을 생성할 수도 있습니다. 다음은 그 방법입니다:

import Link from 'next/link'

function Home() {
  return (
    <ul>
      <li>
        <Link
          href={{
            pathname: '/about',
            query: { name: 'test' },
          }}
        >
          About us
        </Link>
      </li>
      <li>
        <Link
          href={{
            pathname: '/blog/[slug]',
            query: { slug: 'my-post' },
          }}
        >
          Blog Post
        </Link>
      </li>
    </ul>
  )
}

export default Home

위 예제는 다음 링크를 가집니다:

  • 사전 정의된 라우트: /about?name=test
  • 동적 라우트: /blog/my-post

Node.js URL 모듈 문서에서 정의된 모든 속성을 사용할 수 있습니다.

push 대신 URL 교체

Link 구성 요소의 기본 동작은 새 URL을 히스토리 스택에 푸시하는 것입니다. replace 속성을 사용하여 새 항목을 추가하지 않도록 할 수 있습니다. 다음 예제와 같습니다:

<Link href="/about" replace>
  About us
</Link>

페이지 상단으로 스크롤되는 것 방지

Link의 기본 동작은 페이지 상단으로 스크롤됩니다. 해시가 정의되어 있으면 일반 <a> 태그와 같이 특정 ID로 스크롤됩니다. 페이지 상단 / 해시 스크롤을 방지하려면 Linkscroll={false}를 추가하면 됩니다:

<Link href="/#hashid" scroll={false}>
  Disables scrolling to the top
</Link>

Next.js 13 미들웨어와 함께

인증 또는 기타 사용자를 다른 페이지로 리디렉션하는 것과 관련된 목적으로 미들웨어를 사용하는 것이 일반적입니다. <Link /> 구성 요소가 미들웨어를 통해 재작성된 링크를 제대로 미리 가져올 수 있도록 하려면 Next.js에 표시할 URL과 미리 가져올 URL을 모두 알려주어야 합니다. 이것은 불필요한 가져오기(fetch)를 피하기 위해 필요합니다.

예를 들어, 인증 및 방문자 뷰를 가진 /dashboard 경로를 제공하려는 경우 다음과 같이 미들웨어에 비슷한 것을 추가하여 사용자를 올바른 페이지로 리디렉션할 수 있습니다:

// middleware.js
export function middleware(req) {
  const nextUrl = req.nextUrl
  if (nextUrl.pathname === '/dashboard') {
    if (req.cookies.authToken) {
      return NextResponse.rewrite(new URL('/auth/dashboard', req.url))
    } else {
      return NextResponse.rewrite(new URL('/public/dashboard', req.url))
    }
  }
}

이 경우, pages/ 내부의 <Link /> 구성 요소에서 다음 코드를 사용해야 합니다:

// pages/index.js
import Link from 'next/link'
import useIsAuthed from './hooks/useIsAuthed'

export default function Page() {
  const isAuthed = useIsAuthed()
  const path = isAuthed ? '/auth/dashboard' : '/dashboard'
  return (
    <Link as="/dashboard" href={path}>
      Dashboard
    </Link>
  )
}

참고: 동적 라우트를 사용하는 경우 ashref 속성을 적절하게 적용해야 합니다. 예를 들어, /dashboard/[user]와 같은 동적 라우트를 미들웨어를 통해 다른 방식으로 표시하려는 경우 <Link href={{ pathname: '/dashboard/authed/[user]', query: { user: username } }} as="/dashboard/[user]">Profile</Link>와 같이 작성해야 합니다.

0개의 댓글