컴포넌트: Link
컴포넌트: Link | Next.js
섹션 제목: “컴포넌트: Link | Next.js”출처 URL: https://nextjs.org/docs/pages/api-reference/components/link
Link
섹션 제목: “Link”마지막 업데이트: 2026년 2월 20일
<Link>은 HTML <a> 요소를 확장하여 prefetching과 라우트 간 클라이언트 내비게이션을 제공하는 React 컴포넌트입니다. Next.js에서 라우트 간 이동을 수행하는 기본 수단입니다.
기본 사용법:
pages/index.tsx
JavaScriptTypeScript
import Link from 'next/link'
export default function Home() { return <Link href="/dashboard">Dashboard</Link> }Reference
섹션 제목: “Reference”다음 프로퍼티를 <Link> 컴포넌트에 전달할 수 있습니다.
| Prop | Example | Type | Required |
|---|---|---|---|
href | href="/dashboard" | String or Object | Yes |
as | as="/post/abc" | String or Object | - |
replace | replace={false} | Boolean | - |
scroll | scroll={false} | Boolean | - |
prefetch | prefetch={false} | Boolean | - |
shallow | shallow={false} | Boolean | - |
locale | locale="fr" | String or Boolean | - |
onNavigate | onNavigate={(e) => {}} | Function | - |
알아두면 좋은 사항 :
className또는target="_blank"와 같은<a>태그 속성을<Link>에 프로퍼티로 추가하면 기본<a>요소로 전달됩니다.
href (required)
섹션 제목: “href (required)”이동할 경로나 URL입니다.
pages/index.tsx
JavaScriptTypeScript
import Link from 'next/link'
// Navigate to /about?name=test export default function Home() { return ( <Link href={{ pathname: '/about', query: { name: 'test' }, }} > About </Link> ) }replace
섹션 제목: “replace”기본값은false입니다. true이면 next/link가 브라우저 기록 스택에 새 URL을 추가하는 대신 현재 기록 상태를 교체합니다.
pages/index.tsx
JavaScriptTypeScript
import Link from 'next/link'
export default function Home() { return ( <Link href="/dashboard" replace> Dashboard </Link> ) }scroll
섹션 제목: “scroll”기본값은true입니다. Next.js의 <Link> 기본 스크롤 동작은 브라우저의 뒤로/앞으로 이동과 비슷하게 스크롤 위치를 유지하는 것입니다. 새 Page로 이동할 때 Page가 뷰포트에 보이는 한 스크롤 위치가 유지됩니다. 그러나 Page가 뷰포트에 보이지 않으면 Next.js는 첫 번째 Page 요소의 최상단으로 스크롤합니다.
scroll = {false}이면 Next.js는 첫 번째 Page 요소로 스크롤하지 않습니다.
알아두면 좋은 사항 : Next.js는 스크롤 동작을 제어하기 전에
scroll: false인지 확인합니다. 스크롤이 활성화되어 있으면 탐색 대상 DOM 노드를 식별한 뒤 최상위 요소를 검사합니다. 스크롤할 수 없거나 렌더링된 HTML이 없는 요소(스티키/고정 위치 요소,getBoundingClientRect로 계산되는 비가시 요소 등)는 건너뛰며, 뷰포트에 보이는 스크롤 가능한 요소를 찾을 때까지 형제 요소를 계속 탐색합니다.
pages/index.tsx
JavaScriptTypeScript
import Link from 'next/link'
export default function Home() { return ( <Link href="/dashboard" scroll={false}> Dashboard </Link> ) }prefetch
섹션 제목: “prefetch”<Link /> 컴포넌트가 사용자 뷰포트에 들어오면(최초 렌더 또는 스크롤로) 프리패칭이 발생합니다. Next.js는 href가 가리키는 라우트와 데이터를 백그라운드에서 미리 로드하여 클라이언트 내비게이션 성능을 향상시킵니다. 프리패칭은 프로덕션에서만 활성화됩니다.
prefetch 프로퍼티에는 다음 값을 전달할 수 있습니다.
true(default): 라우트 전체와 해당 데이터가 프리패칭됩니다.false: 뷰포트에 진입할 때는 프리패칭하지 않지만, 호버 시에는 진행됩니다. 호버 시에도 완전히 비활성화하려면<a>태그를 사용하거나 프리패칭을 호버에서도 끌 수 있는 App Router를 점진적으로 도입하는 것을 고려하세요.
pages/index.tsx
JavaScriptTypeScript
import Link from 'next/link'
export default function Home() { return ( <Link href="/dashboard" prefetch={false}> Dashboard </Link> ) }shallow
섹션 제목: “shallow”getStaticProps, getServerSideProps, getInitialProps를 다시 실행하지 않고 현재 페이지의 경로만 갱신합니다. 기본값은 false입니다.
pages/index.tsx
JavaScriptTypeScript
import Link from 'next/link'
export default function Home() { return ( <Link href="/dashboard" shallow={false}> Dashboard </Link> ) }locale
섹션 제목: “locale”활성 로케일이 자동으로 접두사로 붙습니다. locale은 다른 로케일을 지정할 수 있습니다. false이면 기본 동작이 비활성화되므로 href에 로케일을 포함해야 합니다.
pages/index.tsx
JavaScriptTypeScript
import Link from 'next/link'
export default function Home() { return ( <> {/* Default behavior: locale is prepended */} <Link href="/dashboard">Dashboard (with locale)</Link>
{/* Disable locale prepending */} <Link href="/dashboard" locale={false}> Dashboard (without locale) </Link>
{/* Specify a different locale */} <Link href="/dashboard" locale="fr"> Dashboard (French) </Link> </> ) }브라우저 URL 바에 표시할 경로를 위한 선택적 데코레이터입니다. Next.js 9.5.3 이전에는 동적 라우트를 위해 사용되었으니, 동작 방식은 이전 문서를 참고하세요.
이 경로가 href와 다르면 이전 문서에 나온 것처럼 기존 href/as 동작이 사용됩니다.
onNavigate
섹션 제목: “onNavigate”클라이언트 내비게이션 중 호출되는 이벤트 핸들러입니다. preventDefault() 메서드가 포함된 이벤트 객체를 받아 필요할 때 내비게이션을 취소할 수 있습니다.
app/page.tsx
JavaScriptTypeScript
import Link from 'next/link'
export default function Page() { return ( <Link href="/dashboard" onNavigate={(e) => { // Only executes during SPA navigation console.log('Navigating...')
// Optionally prevent navigation // e.preventDefault() }} > Dashboard </Link> ) }알아두면 좋은 사항 :
onClick과onNavigate는 비슷해 보이지만 용도가 다릅니다.onClick은 모든 클릭 이벤트에서 실행되지만onNavigate는 클라이언트 측 내비게이션에서만 실행됩니다. 주요 차이점은 다음과 같습니다.
- 수정 키(
Ctrl/Cmd+ 클릭)를 사용할 때 새 탭 내비게이션을 막기 때문에onClick은 실행되지만onNavigate는 실행되지 않습니다.- 외부 URL은 클라이언트 측/동일 출처 내비게이션이 아니므로
onNavigate를 트리거하지 않습니다.download속성이 있는 링크는 브라우저가 다운로드로 처리하므로onClick과는 동작하지만onNavigate와는 동작하지 않습니다.
Examples
섹션 제목: “Examples”다음 예제는 다양한 시나리오에서 <Link> 컴포넌트를 사용하는 방법을 보여줍니다.
Linking to dynamic route segments
섹션 제목: “Linking to dynamic route segments”동적 라우트 세그먼트에는 템플릿 리터럴로 링크 경로를 생성하는 것이 편리합니다.
예를 들어 동적 라우트 pages/blog/[slug].js에 대한 링크 목록을 생성할 수 있습니다.
pages/blog/index.tsx
JavaScriptTypeScript
import Link from 'next/link'
function Posts({ posts }) { return ( <ul> {posts.map((post) => ( <li key={post.id}> <Link href={`/blog/${post.slug}`}>{post.title}</Link> </li> ))} </ul> ) }Scrolling to an id
섹션 제목: “Scrolling to an id”내비게이션 시 특정 id로 스크롤하려면 URL에 # 해시 링크를 추가하거나 href 프로퍼티에 해시 링크만 전달하면 됩니다. <Link>가 <a> 요소로 렌더링되기 때문에 가능합니다.
<Link href="/dashboard#settings">Settings</Link>
// Output <a href="/dashboard#settings">Settings</a>Passing a URL Object
섹션 제목: “Passing a URL Object”Link는 URL 객체를 받을 수 있으며, 이를 자동으로 포맷해 URL 문자열을 생성합니다.
pages/index.ts
JavaScriptTypeScript
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 모듈 문서에 정의된 모든 속성을 사용할 수 있습니다.
Replace the URL instead of push
섹션 제목: “Replace the URL instead of push”Link 컴포넌트의 기본 동작은 새 URL을 history 스택에 push하는 것입니다. 아래 예시처럼 replace prop을 사용하면 새 항목이 추가되지 않도록 할 수 있습니다:
pages/index.js
JavaScriptTypeScript
import Link from 'next/link'
export default function Home() { return ( <Link href="/about" replace> About us </Link> ) }페이지 맨 위로 스크롤되는 동작 비활성화
섹션 제목: “페이지 맨 위로 스크롤되는 동작 비활성화”Link의 기본 동작은 페이지 맨 위로 스크롤하는 것입니다. 해시가 정의되어 있으면 일반 <a> 태그처럼 특정 id로 스크롤합니다. 페이지 상단/해시로 스크롤되지 않도록 하려면 Link에 scroll={false}를 추가하면 됩니다:
pages/index.tsx
JavaScriptTypeScript
import Link from 'next/link'
export default function Home() { return ( <Link href="/#hashid" scroll={false}> Disables scrolling to the top </Link> ) }Proxy에서 링크 미리 가져오기
섹션 제목: “Proxy에서 링크 미리 가져오기”사용자를 다른 페이지로 리라이트해야 하는 인증 등 목적을 위해 Proxy를 사용하는 것이 흔합니다. Proxy를 통한 리라이트와 함께 <Link /> 컴포넌트가 링크를 제대로 미리 가져오게 하려면, Next.js에 표시할 URL과 미리 가져올 URL을 모두 알려야 합니다. 이렇게 해야 올바른 프리페치 경로를 알기 위해 Proxy로 불필요한 페치를 보내지 않습니다.
예를 들어, 인증 사용자와 방문자용 뷰를 모두 제공하는 /dashboard 라우트를 서비스하려면 Proxy에 다음 코드를 추가하여 사용자를 올바른 페이지로 리디렉션할 수 있습니다:
proxy.ts
JavaScriptTypeScript
import { NextResponse } from 'next/server'
export function proxy(request: Request) { const nextUrl = request.nextUrl if (nextUrl.pathname === '/dashboard') { if (request.cookies.authToken) { return NextResponse.rewrite(new URL('/auth/dashboard', request.url)) } else { return NextResponse.rewrite(new URL('/public/dashboard', request.url)) } } }이 경우 <Link /> 컴포넌트에서 다음 코드를 사용하면 됩니다:
pages/index.tsx
JavaScriptTypeScript
'use client'
import Link from 'next/link' import useIsAuthed from './hooks/useIsAuthed' // Your auth hook
export default function Home() { const isAuthed = useIsAuthed() const path = isAuthed ? '/auth/dashboard' : '/public/dashboard' return ( <Link as="/dashboard" href={path}> Dashboard </Link> ) }알아두면 좋아요: Dynamic Routes를 사용하는 경우
as와hrefprops를 조정해야 합니다. 예를 들어/dashboard/authed/[user]처럼 Proxy를 통해 다르게 보여주고 싶은 Dynamic Route가 있다면<Link href={{ pathname: '/dashboard/authed/[user]', query: { user: username } }} as="/dashboard/[user]">Profile</Link>처럼 작성합니다.
버전 기록
섹션 제목: “버전 기록”| Version | Changes |
|---|---|
v15.4.0 | 기본 prefetch 동작에 대한 auto 별칭 추가. |
v15.3.0 | onNavigate API 추가 |
v13.0.0 | 더 이상 자식 <a> 태그가 필요하지 않음. 코드베이스를 자동으로 업데이트할 수 있는 codemod가 제공됨. |
v10.0.0 | 동적 라우트를 가리키는 href props가 자동으로 해석되어 as prop이 더는 필요하지 않음. |
v8.0.0 | 프리페치 성능 향상. |
v1.0.0 | next/link 도입. |
보내기