위 기능을 구현하기 위한 Next.js 의 Parallel Routes, Intercepting Routes에 대해 알아보자.
@team
페이지와 @analytics
페이지를 동시에 렌더링 할 수 있다.@foldername
컨벤션으로 정의되며, 같은 수준의 레이아웃 속성으로 전달된다./dashboard/@analytics/views
의 경우 URL은 /dashboard/views
이다.@analytics
및 @team
슬롯 props를 받고, 이를 children
속성과 함께 병렬로 렌더링할 수 있다.export default function Layout({
children,
team,
analytics,
}: {
children: React.ReactNode
analytics: React.ReactNode
team: React.ReactNode
}) {
return (
<>
{children}
{team}
{analytics}
</>
)
}
default.js
파일을 정의할 수 있다.@team
슬롯에는 settings 디렉토리가 없지만, @analytics
에는 없다./dashboard/settings
로 이동할 때 @team
슬롯은 @analytics
슬롯의 현재 활성 페이지를 유지한 채로 /settings
페이지를 렌더링한다.@analytics
에 대한 default.js
를 렌더링합니다. default.js
가 없으면 404가 대신 렌더링된다.children
은 암묵적인 슬롯이기 때문에 부모 페이지의 활성 상태를 Next.js가 복구할 수 없을 때 children
에 대한 대체를 렌더링하기 위해 default.js
파일을 생성해야 한다./admin
또는 /user
역할에 대해 다른 대시보드 페이지를 렌더링 할 수 있다.import { checkUserRole } from '@/lib/auth'
export default function Layout({
user,
admin,
}: {
user: React.ReactNode
admin: React.ReactNode
}) {
const role = checkUserRole()
return <>{role === 'admin' ? admin : user}</>
}
/feed
경로를 가로채고 URL을 /photo/123
로 보여준다.(..)
구문을 사용하여 정의할 수 있다.(.)
는 동일한 수준의 세그먼트와 일치(..)
는 한 수준 위의 세그먼트와 일치(..)(..)
는 두 수준 위의 세그먼트와 일치(...)
는 루트 앱 디렉토리부터의 세그먼트와 일치(..)photo
디렉토리를 생성함으로써 feed
세그먼트 내부에서 photo
세그먼트를 가로챌 수 있다./login
페이지에 접근할 수 있다./login
라우트를 만들어야 한다.app/login/page.tsx
import { Login } from '@/app/ui/login'
export default function Page() {
return <Login />
}
@auth
슬롯 내에서는 default.js
파일을 추가하여 모달이 활성 상태가 아닐 때 렌더링되지 않도록 한다.app/@auth/default.tsx
export default function Default() {
return null
}
@auth
슬롯 내에서 /(.)login
폴더를 업데이트하여 /login
라우트를 가로채도록 하고, 그런 다음 <Modal>
컴포넌트와 해당 자식을 /(.)login/page.tsx
파일로 가져온다.app/@auth/(.)login/page.tsx
import { Modal } from '@/app/ui/modal'
import { Login } from '@/app/ui/login'
export default function Page() {
return (
<Modal>
<Login />
</Modal>
)
}
<Link>
를 클릭하면 /login
페이지로 이동하는 대신 모달이 열린다./login
으로 이동하면 사용자는 주 로그인 페이지로 이동한다.app/layout.tsx
import Link from 'next/link'
export default function Layout({
auth,
children,
}: {
auth: React.ReactNode
children: React.ReactNode
}) {
return (
<>
<nav>
<Link href="/login">Open modal</Link>
</nav>
<div>{auth}</div>
<div>{children}</div>
</>
)
}
router.back()
을 호출하거나 Link
컴포넌트를 사용할 수 있다.app/ui/modal.tsx
'use client'
import { useRouter } from 'next/navigation'
export function Modal({ children }: { children: React.ReactNode }) {
const router = useRouter()
return (
<>
<button
onClick={() => {
router.back()
}}
>
Close modal
</button>
<div>{children}</div>
</>
)
}
@auth
슬롯을 더 이상 렌더링하지 않아야 하는 경우 Link
컴포넌트를 사용하여 페이지를 떠날 때 모달을 닫을 수 있다.// app/ui/modal.tsx
import Link from 'next/link'
export function Modal({ children }: { children: React.ReactNode }) {
return (
<>
<Link href="/">Close modal</Link>
<div>{children}</div>
</>
)
}