[Next] App Router의 폴더들
[Next] App Router의 폴더들
next 강의를 들으면서 배운 app router에 사용되는 폴더들을 정리하려고 합니다.
- public폴더 : 모두가 접근 가능한 파일 넣는 곳
- src/app 폴더 : 경로 유/무에 따른 최상층 폴더
- route group : route에 영향 안주고, 그룹필 할 수있는 폴더
- paraller route : route에 영향 안주고, 하나의 레이아웃에 두개이상의 페이지를 병렬로 놓을 수 있다.
- intercept route : 경로를 가로채서 현재폴더의 특정부분에 놓을 수 있다.
- dynamic route : 동적 url에 관해 데이터 처리 가능하다.
- private folder : route에 영향 안주고, 공통 컴포넌트 뺄때 유용
public 폴더
넥스트 서버에서 누구나 접근할 수 있도록 해줘서 모든 사람들이 접근 가능한 이미지 등을 넣어 두면 된다.
// / + 파일 이름을 입력하면 public폴더안의 이미지와 연결된다.
/'이미지 이름'
src / app 폴더
app폴더 = 주소( 라우팅 )와 관련된 파일만 들어감
src폴더 = 주소( 라우팅 )와 관련없는 ts / js 파일들을 app 폴더 밖, src폴더 안에 넣어두기 좋다.
경로를 지정할 때 src 폴더가 있다면 @ -> src로 없다면 @ --> app 폴더로 사용할 수 있다.
src폴더를 @로 대체. ../ ../ 안써도됨 --> app폴더가 최상위면 app, src가 최상위면 src
import ActionButtons from "@/app/(afterLogin)/_component/ActionButtons";
**path alies = /.. /.. 이런것들 안스고 @/app/이런식으로 쓸수 있게 아니면 커스텀해서 다른걸로 ^/app/이런식으로 커스텀 가능 유무
** app폴더에는 라우팅과 관련된 파일만 들어가는데, url에 영향을 주지 않는 폴더들이 몇개 있다.
주소창에 안뜨는 app폴더안에 있는 폴더?
route group '(beforeLogin)' = 주 기능은 그룹화하고 레이아웃을 두는것
parallel route '@modal' = 한화면에 두가지화면을 동시에 보여주기, 병렬로 레이아웃 띄우게
private route '_component' = 주소창에 안뜨고 폴더 정리용 (공통으로 쓰는 컴포넌트 같은)
Route Group (라우트 그룹 : ())
(폴더명) = ()는 주소창에 관여를 하지 않는다. 그룹은 만들 수 있다.
app폴더 안에는 주소(라우팅)와 관련된 파일만 들어간다고 했는데 app/(afterLogin)/home 하면 주소는 /home이다.
주소에 관여하지 않으면서 그룹화할수 있어 편리하다
(afterLogin) 이것만의 layout.tsx 하나 더 만들 수 있다.
주소에 영향은 끼치지 않고, 그룹화는 할 수 있으며, layout.tsx는 만들 수 있다.
(beforeLogin), (afterLogin) 이런식으로 폴더 두개를 만들게 되면 로그인 전의 레이아웃들, 로그인 후의 레이아웃들로 구분지어 알아보기 쉽게 그룹핑할 수 있고 주소에는 영향주지 않아서 편리하다.
app폴더에 page.tsx가 없고 아래의 최상위 폴더가 두 그룹 폴더일 경우에 둘중 하나에만 page.tsx가 들어가야 기본 페이지로 인식한다. 그렇지 않으면 에러 발생. (app 폴더에 page.tsx가 두개 있는것과 같음. 주소에 영향주지 않기 때문에)
다른 말로 그룹핑의 기준이 레이아웃이 될 수있다.
Parallel routing (페러렐 라우트 : @)
parallel은 평행, 병렬의 뜻을 가지고 있다.
즉 경로를 병렬로 사용할 수 있다는 뜻이다.
하나의 레이아웃 안에서 여러 라우트 구성을 동시에 동작시킬 수 있게 해줍니다.
동일한 레이아웃 내에서 하나 이상의 페이지를 동시에 또는 조건부로 렌더링할 수 있습니다.
이는 대시보드 및 소셜 사이트의 피드와 같이 앱의 매우 동적인 섹션에 유용합니다.
예를 들어 대시보드를 고려하면 병렬 경로를 사용하여 team및 analytics페이지를 동시에 렌더링할 수 있습니다.
슬롯?
명명된 슬롯을 사용하여 생성됩니다 .
슬롯은 규칙에 따라 정의됩니다 @folder.
각 슬롯은 레이아웃의 한 부분에 해당하며 독립적으로 콘텐츠를 렌더링할 수 있습니다.
예를 들어, 다음 파일 구조는 두 개의 슬롯을 정의합니다: @analytics및 @team:
슬롯은 공유 상위 레이아웃에 소품으로 전달됩니다.
위의 예에서 구성 요소는 이제 및 슬롯 소품을 app/layout.js허용 하고 소품과 함께 병렬로 렌더링할 수 있습니다 . @analytics @team children
그러나 슬롯은 URL 구조에 영향을 주지 않습니다.
예를 들어 의 경우 URL은 슬롯이므로 URL이 됩니다 ./@analytics/views ---> /views
Default.tsx?
default.tsx = 페러렐라우트의 기본값. 페러렐라우트가 필요없을때.
주소가 z.com일 때(localhost:3000 or 메인화면)는 children -> page.tsx, modal -> @modal/default.tsx (page.tsx만들어줘도 되는데, 넣을 컨텐츠 없어서 default로 왜냐하면 return null이라 컨텐츠없다.
default.tsx가 없다면 404에러 뜬다.
주소가 localhost:3000/i/flow/login 때는 children -> i/flow/login/page.tsx, modal -> @modal/i/flow/login/page.tsx
Intercept routing (인터셉트 라우트 : (.), (..), (..)(..), (...))
경로를 가로채면 현재 레이아웃 내 애플리케이션의 다른 부분에서 경로를 로드할 수 있습니다.
이 라우팅 패러다임은 사용자가 다른 컨텍스트로 전환하지 않고도 경로의 내용을 표시하려는 경우 유용할 수 있습니다.
규칙을 사용하여 정의할 수 있는데 (..), 이는 상대 경로 규칙과 유사 ../하지만 세그먼트에 대한 것입니다.
- (.)동일한 수준 의 세그먼트를 일치시키려면
- (..)한 수준 위의 세그먼트와 일치시키려면
- (..)(..)두 수준 위의 세그먼트와 일치시키려면
- (...)루트 app 디렉터리 의 세그먼트를 일치시키려면
예를 들어 디렉터리 를 생성하여 세그먼트 photo내에서 세그먼트 를 가로챌 수 있습니다 .feed(..)photo
클라이언트에서 라우팅할 때만(<Link>) 인터셉트 라우팅이 적용된다. --> 만약 로그인 버튼을 클릭했을때 인터셉트 주소로 redirect 시키고 싶다면 기존폴더(서버컴포넌트)의 것이 아닌 클라이언트 컴포넌트의 리다이랙트를 해줘야한다.
*import {redirect} from 'next/navigation'의 redirect는 서버 컴포넌트에서만 작동한다.
*그래서 라우팅했을 대는 인터셉트 라우트로 이동하고, 새로고침했을땐 라우팅당한 라우트로 이동하게 된다.
Parallel routing + Intercept routing으로 경로가 있는 modal 만들기?
(beforeLogin)/page.tsx와 (beforeLogin)/@modal/i/flow/login/page.tsx가 같이 떴으면 좋겠다.
📦(beforeLogin)
┣ 📂@modal
┃ ┣ 📂(.)i
┃ ┃ ┗ 📂flow
┃ ┃ ┃ ┣ 📂login
┃ ┃ ┃ ┃ ┗ 📜page.tsx
┃ ┃ ┃ ┗ 📂signup
┃ ┃ ┃ ┃ ┗ 📜page.tsx
┃ ┗ 📜default.tsx
┣ 📂i
┃ ┗ 📂flow
┃ ┃ ┣ 📂login
┃ ┃ ┃ ┗ 📜page.tsx
┃ ┃ ┗ 📂signup
┃ ┃ ┃ ┗ 📜page.tsx
┣ 📂login
┃ ┗ 📜page.tsx
┣ 📂_component
┃ ┣ 📜login.module.scss
┃ ┣ 📜LoginModal.tsx
┃ ┣ 📜main.module.scss
┃ ┣ 📜Main.tsx
┃ ┣ 📜signup.module.scss
┃ ┗ 📜SignupModal.tsx
┣ 📜layout.tsx
┗ 📜page.tsx
*(.)i 로 되어있어 동일한 경로로 표시되는데 왜냐하면 부모폴더인 @modal, (beforeLogin)모두 경로에 영향을 주지 않음으로 (.)i 와 i는 동일한 수준에 있다고 할 수 있다.
위처럼 경로를 만들게 되면,
클라이언트에서 /i/flow/login 경로로 라우팅하게 되면 (.)i/flow/login이 인터셉트하게 된다.
- /i/flow/login = 인터셉트 당한 경로
- (.)i/flow/login = 인터셉트 한 경로
/(beforeLogin)/layout.tsx
import { ReactNode } from 'react';
import styles from '@/app/page.module.scss';
type Props = { children: ReactNode; modal: ReactNode };
export default function Layout({ children, modal }: Props) {
return (
<div className={styles.container}>
비포로그인 레이아웃
{children}
{modal}
</div>
);
}
메인페이지 (beforeLogin)/page.tsx에서 인터셉트당한 경로로 라우팅하면,
인터셉트한 경로로 이동하게 되는데 여기서 이경로는 @modal로 페러릴라우트로 되어있다.
현재 메인페이지 url은 바뀜. '/' --> '/i/flow/lgoin' 그러나 화면은 기존page가 child로 가고 인터셉트된 페러렐은 modal로 넘어와서 children과 함게 뿌려진다.
그리고 modal 레이아웃에 모달 스타일을 입혀주면
- route는 인터셉트한 것으로 이동하면서,
- 페이지는 그대로 있으면서,
- 인터셉트한 레이아웃은 모달창으로 뿌려줄 수 있게 된다.
그러면 인터셉트당한 i폴더는 필요없는게 아닌가?
그렇지 않다. 왜냐하면 인터셉트는 라우팅했을때만 먹히는것 이기때문에, 새로고침했을때에는
인터셉트당한 i가 떠야하기 때문에 유지해줘야 한다.
그렇지 않다면 없는 페이지 에러가 발생한다.
Private Folder (프라이빗 폴더 : _)
위의 i폴더와 (.)i폴더 하위의 pages.tsx는 같은 화면이기 대문에 코드가 같다.
이러한 공통적인 코드를 컴포넌트로 때로 뺄때 유용한 폴더가 프라이빗 폴더
- 폴더 이름 앞에 언더바(_)를 붙이면, 해당 폴더 하위 폴더 및 파일을 라우팅에서 제외시킬 수 있다.
- UI 로직과 라우팅 로직을 분리하는 경우
- 프로젝트 및 Next.js 생태계 전반에 걸쳐 내부 파일을 일관되게 구성하는 경우
- 코드 편집기에서 파일을 정렬하고 그룹화하는 경우
- 향후 Next.js 파일 규칙과의 잠재적인 이름 충돌을 피하는 경우
Dynamic routing (동적 라우트 : [])
동적인 url정보를 처리할 수 있습니다.
[folderName]. 예를 들어, [id]또는 [slug].
[folderName]
export default function Page({ params }: { params: { slug: string } }) {
return <div>My Post: {params.slug}</div>
}
예시: URL params
app/blog/[slug]/page.js /blog/a { slug: 'a' }
app/blog/[slug]/page.js /blog/b { slug: 'b' }
app/blog/[slug]/page.js /blog/c { slug: 'c' }
[...folderName]
대괄호 안에 줄임표를 추가하면 동적 세그먼트를 모든 후속 세그먼트 로 확장할 수 있습니다
[...folderName].
예를 들어 는 , , 등도 app/shop/[...slug]/page.js일치합니다
예시 url params
app/shop/[...slug]/page.js /shop/a { slug: ['a'] }
app/shop/[...slug]/page.js /shop/a/b { slug: ['a', 'b'] }
app/shop/[...slug]/page.js /shop/a/b/c { slug: ['a', 'b', 'c'] }
[[...folderName]]
이중 대괄호 안에 매개변수를 포함하여 포괄 세그먼트를
선택사항으로[[...folderName]] 만들 수 있습니다 .
예를 들어 , , 외에도 , 도 일치 app/shop/[[...slug]]/page.js합니다
catch-all 세그먼트 와 선택적 catch-all 세그먼트 의 차이점은 선택 사항을 사용하면
매개변수가 없는 경로도 일치한다는 것입니다( /shop위 예에서).
예시 url params
app/shop/[[...slug]]/page.js /shop {}
app/shop/[[...slug]]/page.js /shop/a { slug: ['a'] }
app/shop/[[...slug]]/page.js /shop/a/b { slug: ['a', 'b'] }
app/shop/[[...slug]]/page.js /shop/a/b/c { slug: ['a', 'b', 'c'] }
Typescript
TypeScript를 사용할 때 params구성된 경로 세그먼트에 따라 유형을 추가할 수 있습니다.
export default function Page({ params }: { params: { slug: string } }) {
return <h1>My Page</h1>
}
예시 url params
app/blog/[slug]/page.js { slug: string }
app/shop/[...slug]/page.js { slug: string[] }
app/shop/[[...slug]]/page.js { slug?: string[] }
app/[categoryId]/[itemId]/page.js { categoryId: string, itemId: string }
참조!
https://www.inflearn.com/course/next-react-query-sns%EC%84%9C%EB%B9%84%EC%8A%A4#
Next + React Query로 SNS 서비스 만들기 | 조현영 - 인프런
조현영 | 리액트18 & 넥스트14 & 리액트쿼리5 & Next Auth5 & MSW2 & socket.io4 & zustand 스택으로 트위터(X.com)와 유사한 SNS 서비스를 만들어봅니다. 끝으로 검색엔진 최적화를 위한 S...
www.inflearn.com
https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes
Routing: Dynamic Routes | Next.js
Dynamic Routes can be used to programmatically generate route segments from dynamic data.
nextjs.org