Headercomponents/ 루트에 있고 Footercomponents/sections/ 안에 있다. 같은 레이아웃 조각인데 사는 곳이 다르다.

안 A   폴더 이름으로 가른다.  레이아웃은 layout/, 섹션은 sections/
안 B   붙이는 자리로 가른다.  layout 이 그리는 것과 페이지가 그리는 것

처음엔 폴더를 정리하는 문제로 보였다. 그런데 세어 보니 폴더가 갈린 건 원인이 아니라 결과였다.


먼저: 이미 9곳에서 푸터가 빠져 있었다

이건 원칙이 아니라 이 표준을 급하게 만든 사실이다.

라우트 13개를 하나씩 열어 셌다.

Header        13 / 13 곳    layout.js 가 그린다
Footer         4 / 13 곳    페이지가 손으로 import 한다
MobileCtaBar  12 / 13 곳    페이지가 손으로 import 한다

푸터가 없는 9곳이다.

/faq   /faq/[id]   /inquiries   /inquiries/detail   /inquiries/new
/privacy   /reviews   /reviews/[id]   /terms

/privacy/terms에도 없다. 회사 정보와 약관 링크가 푸터에 있는데 그 페이지들에서 빠졌다. 전부 누락이지 의도가 아니다.

원인은 폴더가 아니라 붙이는 방식이었다.

새 페이지를 만든다
  → Header 는 자동으로 붙는다        layout 이 그리므로
  → Footer 는 안 붙는다             페이지가 손으로 import 해야 하므로
  → 까먹으면 그 페이지만 푸터가 없다

Headercomponents/ 루트에 있고 Footersections/에 들어간 것도 그래서다. 붙이는 자리가 다르니 사는 곳도 갈렸다.


먼저: 정적 export라 서버가 화면 크기를 모른다

이 제약이 뒤의 원칙 5를 미리 정했다.

lib/api.js 주석에 적혀 있다.

이 사이트는 정적 export(output: 'export') 라 Next 서버가 없습니다.

빌드 때 HTML을 만들어 모든 기기에 같은 것을 보낸다. 서버가 User-Agent 도 화면 크기도 모른다. 그래서 기기별로 다른 화면을 주는 방법이 CSS 뿐이다.


원칙 1. 붙이는 자리로 가른다 — 폴더 이름으로 가르지 않는다

무엇을 기준으로 컴포넌트를 나누는가.

안 A — 성격으로 가른다. 「레이아웃」·「섹션」·「도메인」·「유틸」로 이름 붙여 폴더를 나눈다. 얻는 것은 폴더 이름만 보고 무엇인지 아는 것이다.

버린 이유는 성격이 경계선에서 흐려진다는 것이다. MobileCtaBar는 레이아웃인가 섹션인가. InquiryStatusBadge는 도메인인가 UI인가. 판단이 필요한 기준은 사람마다 다르게 답하고, 실제로 HeaderFooter가 그렇게 갈렸다.

골랐다 — 안 B, 「누가 그리는가」로 가른다.

layout 이 그린다              →  페이지는 존재를 모른다
그 화면 갈래 안에서만 쓴다     →  그 갈래의 일부다
갈래 밖에서도 쓴다            →  공용 조각이다

안 A가 못 지켜주는 것은 답이 코드에 이미 있다는 것이다. 「이건 레이아웃인가」는 의견이지만 「layout.js 가 이걸 그리는가」는 파일을 열면 나온다. 세 갈래 어디에도 안 걸리는 컴포넌트가 없다.

그리고 이 기준이 푸터 누락을 없앤다. 「모든 페이지에 뜬다」가 곧 「layout 이 그린다」이므로, 페이지가 붙일 일이 없어 빠질 자리도 없다.


원칙 2. 자리는 셋이고, 페이지 전용은 그 페이지 옆에 둔다

세 갈래를 어디에 두는가.

갈래 어디에 이 프로젝트의 예
layout 이 그린다 components/layout/ Header · Footer · SocialRail · GoogleAnalytics
그 화면 갈래 안에서만 쓴다 app/<갈래>/_components/ Hero · WhyUs · Process (홈) · AccountForm (계정 화면)
갈래 밖에서도 쓴다 components/ ReviewCard · ImagePlaceholder · icons · AdminSelect

두 번째가 app/ 안으로 들어가는 것이 Next.js 가 권하는 방식이다. 밑줄로 시작하는 폴더는 라우팅에서 빠진다.

Private folders can be created by prefixing a folder with an underscore: _folderNameopting the folder and all its subfolders out of routing. app/blog/_components/Post.tsxNot routable; safe place for UI utilities

실측이 이 셋과 정확히 맞았다. sections/ 의 여덟(Hero·WhyUs·Process·ServiceIntro·Reviews·ContactCTA·BottomCTA·Footer)은 Footer 하나만 빼고 전부 홈 한 곳에서만 쓰인다. Footer 가 거기 섞여 있던 것이 어긋남이었다.

대가는 페이지 전용이 여러 곳으로 흩어지는 것이다. 지금은 sections/ 한 폴더에 모여 있어 한눈에 보이는데, 라우트마다 _components/ 가 생기면 전체 목록을 볼 수 없다. 그래도 그쪽을 고른 이유는 「이게 어디서 쓰이지」를 찾는 일이 「전체 목록을 보는」 일보다 훨씬 잦기 때문이다. 페이지 옆에 있으면 그 질문에 답이 필요 없다.


원칙 3. 공용인지는 개수가 아니라 갈래 밖에서 쓰이는지로 묻는다

「몇 곳에서 쓰나」로 묻지 않는다. admin 을 재보니 AccountForm · CaregiverForm · ReviewForm 이 전부 2곳에서 쓰인다 — 만들기 화면과 고치기 화면이 같은 폼을 쓰기 때문이다.

/accounts/new         계정 만들기   ┐
/accounts/[id]/edit   계정 고치기   ┘  둘 다 AccountForm 을 쓴다

개수로 물으면 이건 「여러 곳」이라 공용으로 간다. 그런데 계정 화면 밖에서는 아무도 안 쓴다. 공용 폴더에 넣으면 「아무 데서나 쓰는 것」과 「계정 화면에서만 쓰는 것」이 섞이고, 지금 components/ 가 잡동사니가 된 그 과정이 다시 시작된다.

그래서 _components/ 는 페이지 하나가 아니라 갈래에 딸린다. Next.js 문서의 예시(app/blog/_components/Post.tsx)도 블로그 갈래 전체가 쓰는 것이라는 뜻이다.

app/(dashboard)/accounts/
  _components/AccountForm.js     ← 이 갈래 둘이 같이 쓴다. 밖에서는 안 쓴다
  new/page.js
  [id]/edit/page.js

올리기만 하고 내리지 않는다. 두 번째 갈래에서 쓰게 되면 그때 components/ 로 올린다. 반대로 「일단 공용에 두고 안 쓰이면 내린다」는 안은 버렸다 — 내리는 일은 급하지 않아 아무도 안 하고, 공용 폴더만 계속 커진다. 올릴 때는 반대로 이유가 눈앞에 생긴다: 다른 화면에서 ../../accounts/_components/ 를 import 하려는 순간 그 경로 자체가 「여기 있으면 안 된다」는 신호다.

내리는 규칙은 정하지 않는다. 「안 쓰이게 됐는지」를 알려면 매번 세어봐야 하는데 그건 아무도 안 한다. 올리는 쪽만 규칙으로 두면 잘못 올라간 것이 있어도 더 늘지는 않는다.


원칙 4. 성격이 같은 무리는 route group 으로 layout 을 나눈다

MobileCtaBar 는 13곳 중 12곳에 있고 /inquiries/new 하나에만 없다. 문의 작성 폼에서 하단 고정 바가 입력을 가려 뺀 것이고, 의도한 것이다.

그러면 원칙 1이 걸린다 — 「모든 페이지에 뜨는 것은 layout 이 그린다」인데 하나만 예외다.

안 A — layout 에 넣고 그 페이지에서 숨긴다. MobileCtaBar 안에서 usePathname() 으로 경로를 보고 특정 경로면 null 을 돌려준다. 버린 이유는 컴포넌트가 자기가 어디 뜨는지 알게 되는 것이다. 그 목록을 페이지가 늘 때마다 고쳐야 하고, 까먹으면 빠진다 — 방금 푸터가 9곳에서 빠진 것과 똑같은 모양이다.

골랐다 — 안 B, route group 으로 layout 을 나눈다. 이건 지어낸 방식이 아니다 — 같은 프로젝트의 admin 이 이미 그렇게 하고 있다.

app/(auth)/layout.js        인증 화면 묶음
app/(dashboard)/layout.js   Sidebar · AccessGate · SessionProvider 를 여기서 그린다

라우트 28개짜리 admin 은 레이아웃 조각을 layout 이 그리고 성격이 다른 무리를 그룹으로 갈라 두고 있었다. client 만 어긋나 있었다.

app/
  layout.js              Header · Footer · SocialRail · GoogleAnalytics    모든 페이지
  (browse)/
    layout.js            + MobileCtaBar
    page.js  about/  care/  faq/  fee/  privacy/  reviews/  terms/
    inquiries/page.js    inquiries/detail/page.js
  (form)/
    layout.js            하단 바 없음 — 입력을 가린다
    inquiries/new/page.js

그룹 이름을 (with-cta) 가 아니라 (browse) · (form) 으로 지었다. 전자는 「예외 하나를 위한 장치」로 읽히고, 후자는 「입력하는 페이지에는 하단 고정 바를 두지 않는다」는 규칙이 된다. 앞으로 입력 화면이 늘면 (form) 에 넣기만 하면 되고, 예외 목록을 어딘가 적어둘 일이 없다.

/inquiries/inquiries/new 가 다른 그룹에 있어도 된다. Next.js 문서가 막는 건 같은 URL 이 되는 경우뿐이다.

Conflicting paths: Routes in different groups should not resolve to the same URL path.

대가는 폴더 깊이가 한 겹 늘고, 라우트가 어느 그룹에 있는지 봐야 하는 것이다.


원칙 5. 레이아웃 조각의 기기별 차이는 CSS 가 만든다

레이아웃은 모든 기기에서 같지 않다. 오히려 정반대인 것이 있다.

.mobile-cta-bar { display: none }
@media (max-width: 767px) { .mobile-cta-bar { display: flex } }   /* 모바일에서만 */

.social-rail { display: none }
@media (min-width: 768px) { .social-rail { display: flex } }      /* 데스크톱에서만 */

같은 목적(연락 유도)을 모바일은 하단 고정 바로, 데스크톱은 우측 세로 레일로 둔다. Header 안의 CTA 링크도 768px 이상에서만 뜬다.

그래도 layout 은 둘 다 그린다. 페이지도 컴포넌트도 화면 크기를 모르고, CSS 만 안다.

안 A — JS 로 화면을 재서 조건부로 그린다. HTML 이 가벼워진다. 버린 이유는 정적 export 라 첫 HTML 에 답이 없다는 것이다. 브라우저가 JS 를 돌린 뒤에야 결정되므로 첫 화면에 깜빡임이 생기고, JS 가 꺼진 환경에서는 아예 안 뜬다.

골랐다 — 안 B, 전부 그리고 CSS 가 가른다. 안 A 가 못 지켜주는 것은 서버가 화면 크기를 몰라도 되는 것이다. 빌드 때 만든 HTML 하나가 모든 기기에서 옳다.

대가는 안 보이는 것도 HTML 에 남는 것이다. 모바일에서도 SocialRail 마크업이 실려 오고, 데스크톱에서도 MobileCtaBar 가 실려 온다. 레이아웃 조각은 몇 개 안 되므로 그 무게를 감수한다 — 대신 목록이 긴 것(후기 수십 건 같은)을 이렇게 양쪽 다 그리지는 않는다.


판단 기준 정리

질문 결론
무엇으로 가르나 누가 그리는가 성격은 의견이지만 「layout 이 그리는가」는 파일을 열면 나온다
모든 페이지에 뜬다 components/layout/ layout 이 그린다. 페이지는 존재를 모른다
그 화면 갈래 안에서만 쓴다 app/<갈래>/_components/ 개수가 아니라 갈래로 묻는다. 밑줄 폴더는 라우팅에서 빠진다
갈래 밖에서도 쓴다 components/ 공용 조각
갈래 안에 있던 걸 밖에서도 쓰게 됐다 올린다 내리는 규칙은 두지 않는다 — 아무도 안 한다
대부분에 뜨는데 하나만 빼야 한다 route group 성격 이름으로 짓는다. 예외 목록을 만들지 않는다
컴포넌트가 경로를 봐도 되나 안 된다 페이지 늘 때마다 목록을 고쳐야 하고 까먹으면 빠진다
기기별로 다르게 보여야 한다 CSS 가 가른다 정적 export 라 서버가 화면을 모른다
그럼 안 보이는 것도 실려 오나 그렇다 레이아웃 조각은 몇 개 안 되므로 감수한다

이 표준을 정하기까지

폴더 정리 문제로 보였다. Headercomponents/ 루트에 있고 Footercomponents/sections/ 안에 있다 — 같은 레이아웃 조각인데 사는 곳이 다르니 폴더 규칙을 세우면 될 일로 보였다.

세어 보고 나서 원인이 뒤집혔다. 각 컴포넌트가 몇 곳에서 쓰이는지 셌더니 Header 가 1곳, Footer 가 4곳, MobileCtaBar 가 13곳이었다. Header 가 1곳인 게 이상해서 열어보니 layout.js 가 그리고 있었고, FooterMobileCtaBar 는 페이지마다 손으로 붙이고 있었다. 폴더가 갈린 것은 결과였고 원인은 붙이는 자리였다.

그래서 라우트 13개를 하나씩 열어 확인했다. 푸터가 4곳에만 있었다 — 9곳에서 빠져 있었다. /privacy/terms 에도 없었다. 「지금은 우연히 다 맞다」와 「이미 어긋나 있다」는 같은 규칙을 정하더라도 급한 정도가 달라서 재봤는데, 이미 어긋나 있었다.

기준을 「성격」에서 「누가 그리는가」로 바꾼 것이 이 표준의 전부다. 성격으로 가르면 MobileCtaBar 가 레이아웃인지 섹션인지에서 사람마다 답이 갈린다. 「layout.js 가 이걸 그리는가」는 파일을 열면 답이 나온다. 그리고 그 기준이 푸터 누락을 구조적으로 없앤다 — 페이지가 붙일 일이 없으면 빠질 자리도 없다.

예외 하나가 원칙을 시험했다. MobileCtaBar 가 12/13 이고 /inquiries/new 에만 없는데, 입력을 가려서 뺀 의도였다. 컴포넌트가 usePathname() 으로 경로를 보고 숨는 안이 제일 쉬웠지만, 그건 방금 푸터가 빠진 것과 똑같은 모양이다 — 목록을 사람이 관리하고 까먹으면 어긋난다. route group 으로 가르되 이름을 (browse) · (form) 으로 지어 예외가 아니라 부류가 되게 했다.

표준을 쓰고 나서 admin 을 재보다 구멍을 하나 찾았다. 원칙 2 를 「몇 곳에서 쓰나」로 물었는데, admin 의 폼들이 전부 2곳이었다 — 만들기 화면과 고치기 화면이 같은 폼을 쓴다. 개수로 물으면 「여러 곳」이라 공용으로 가는데 계정 화면 밖에서는 아무도 안 쓴다. 질문을 「어느 갈래 밖에서도 쓰나」로 바꾸자 답이 제자리를 찾았다. 어긋난 게 아니라 경우 하나를 안 다룬 것이라 장부에 열지 않고 그 자리에서 채웠다.

그리고 admin 이 원칙 3 을 이미 하고 있다는 것도 그때 알았다. route group 으로 (auth)(dashboard) 를 가르고 레이아웃 조각을 layout 이 그린다. 제안한 방식이 「생각해낸 것」이 아니라 「한쪽이 이미 검증한 것」이었다.

마지막으로 「모든 기기에서 같은 레이아웃인가」를 물었고, 아니었다. MobileCtaBar 는 767px 이하에서만, SocialRail 은 768px 이상에서만 뜬다 — 정반대다. 같은 목적을 화면에 따라 다른 자리에 둔 것이다. 그런데 이 사이트는 정적 export 라 서버가 화면 크기를 모른다. 빌드 때 HTML 하나를 만들어 모두에게 보내므로 가르는 방법이 CSS 뿐이고, 그래서 「layout 은 전부 그리고 CSS 가 가른다」를 원칙으로 못 박았다. 선택지가 하나뿐인 자리라 안을 지어내지 않았다.


정리

  • 폴더 이름이 아니라 「누가 그리는가」로 가른다. 성격은 의견이지만 붙이는 자리는 파일에 적혀 있다.
  • 모든 페이지에 뜨는 것은 layout 이 그린다. 페이지가 손으로 붙이면 빠진다 — 실제로 푸터가 9곳에서 빠졌다.
  • 자리는 셋이다. components/layout/ · app/<갈래>/_components/ · components/.
  • 「몇 곳에서 쓰나」가 아니라 「어느 갈래 밖에서도 쓰나」로 묻는다. 만들기·고치기 화면이 같은 폼을 쓰는 것은 공용이 아니다.
  • 올리기만 하고 내리지 않는다. 내리는 일은 아무도 안 해서, 규칙으로 두면 안 지켜지는 규칙이 하나 는다.
  • 대부분에 뜨는데 하나만 빼야 하면 route group 으로 나눈다. 그룹 이름은 성격으로 짓는다.
  • 컴포넌트가 경로를 보고 자기를 숨기지 않는다. 그 목록을 사람이 관리하게 되면 까먹는다.
  • 기기별 차이는 CSS 가 만든다. 정적 export 라 서버가 화면을 모르고, layout 은 전부 그린다.

AI 코드 어시스턴트에 바로 적용하기

Claude Code · Codex — .claude/skills/component-placement-standard/SKILL.md · .agents/skills/component-placement-standard/SKILL.md

두 파일은 바이트까지 같아야 한다. .agents 쪽은 tools/agents-skills.rb 가 뽑는 생성물이다.

---
name: component-placement-standard
description: 프론트엔드 컴포넌트를 어디에 두고 무엇이 그리는지 정한다. 레이아웃 조각과 페이지 전용과 공용 조각을 가르는 기준, route group 으로 layout 을 나누는 자리, 기기별로 다르게 보일 때의 방법을 담는다. 컴포넌트를 새로 만들 때, 모든 페이지에 뜨는 것을 추가할 때, 페이지마다 다르게 보여야 할 때 적용한다. Next.js App Router 기준이다.
---

# 컴포넌트 자리 표준

**폴더 이름이 아니라 「누가 그리는가」로 가른다.**

성격(레이아웃이냐 섹션이냐)은 경계선에서 사람마다 답이 갈린다. **「`layout.js` 가 이걸 그리는가」는 파일을 열면 나온다.**

## 자리는 셋이다

| 갈래 | 어디에 |
|---|---|
| **layout 이 그린다** — 모든 페이지에 뜬다 | `components/layout/` |
| **그 화면 갈래 안에서만 쓴다** | `app/<갈래>/_components/` |
| **갈래 밖에서도 쓴다** | `components/` |

- **모든 페이지에 뜨는 것을 페이지가 손으로 import 하지 않는다.** 새 페이지에서 까먹으면 그 페이지만 빠진다.
- 밑줄로 시작하는 폴더는 **라우팅에서 빠진다.** 페이지 전용 컴포넌트를 그 페이지 옆에 두는 Next.js 공식 방식이다.
- **「몇 곳에서 쓰나」로 묻지 않는다. 「어느 갈래 밖에서도 쓰나」로 묻는다.** 만들기 화면과 고치기 화면이 같은 폼을 쓰는 것은 2곳이지만 공용이 아니다 — 그 갈래 밖에서는 아무도 안 쓴다.
- `_components/`**페이지 하나가 아니라 갈래에 딸린다.** `app/accounts/_components/AccountForm.js``new``[id]/edit` 이 같이 쓴다.
- **올리기만 하고 내리지 않는다.** 두 번째 갈래에서 쓰게 되면 그때 `components/` 로 올린다. 다른 화면에서 `../../accounts/_components/` 를 import 하려는 순간 그 경로가 신호다.
- **내리는 규칙은 두지 않는다.** 「안 쓰이게 됐는지」는 매번 세어야 알 수 있고 그건 아무도 안 한다.

## 대부분에 뜨는데 하나만 빼야 할 때

**route group 으로 layout 을 나눈다.**

```
app/
  layout.js              모든 페이지 공통
  (browse)/
    layout.js            + 하단 고정 바
    about/  faq/  reviews/  ...
  (form)/
    layout.js            하단 바 없음 — 입력을 가린다
    inquiries/new/
```

- **그룹 이름을 성격으로 짓는다.** `(with-cta)` 가 아니라 `(browse)` · `(form)` 이다. 그래야 「예외 하나」가 아니라 **부류**가 되고, 같은 성격이 늘면 넣기만 하면 된다.
- **컴포넌트가 `usePathname()` 으로 경로를 보고 자기를 숨기지 않는다.** 그 목록을 사람이 관리하게 되고, 페이지가 늘 때 까먹으면 어긋난다.
- 다른 그룹에 같은 URL 이 생기면 에러다. **다른 URL 이면 같은 경로 아래라도 그룹이 갈려도 된다** (`/inquiries``/inquiries/new`).

## 기기별로 다르게 보여야 할 때

**layout 은 전부 그리고 CSS 가 가른다.**

```css
.mobile-cta-bar { display: none }
@media (max-width: 767px) { .mobile-cta-bar { display: flex } }

.social-rail { display: none }
@media (min-width: 768px) { .social-rail { display: flex } }
```

- **JS 로 화면을 재서 조건부로 그리지 않는다.** 정적 export 면 첫 HTML 에 답이 없어 깜빡이고, JS 가 꺼지면 아예 안 뜬다.
- **안 보이는 것도 HTML 에 실린다.** 레이아웃 조각은 몇 개 안 되므로 감수한다.
- **목록이 긴 것을 양쪽 다 그리지 않는다.** 후기 수십 건 같은 것은 이 방식을 쓰지 않는다.

## 하지 않는 것

- **모든 페이지에 뜨는 것을 페이지가 import 하지 않는다.**
- **컴포넌트가 자기가 어디 뜨는지 알게 하지 않는다.** 경로 목록을 컴포넌트 안에 두지 않는다.
- **개수로 공용 여부를 정하지 않는다.** 갈래 밖에서 쓰이는지로 정한다.
- **성격 이름으로 폴더를 나누지 않는다.** `sections/` · `common/` 처럼 판단이 필요한 이름은 경계선에서 갈린다.
- **route group 이름을 예외 표시로 짓지 않는다.** 무엇을 하는 페이지 무리인지로 짓는다.
- **정적 export 에서 JS 로 화면 크기를 재어 레이아웃을 가르지 않는다.**

GitHub Copilot — .github/instructions/component-placement-standard.instructions.md

---
description: 프론트엔드 컴포넌트를 어디에 두고 무엇이 그리는가
applyTo: "**"
---

# 컴포넌트 자리

- **폴더 이름이 아니라 「누가 그리는가」로 가른다.** 성격(레이아웃이냐 섹션이냐)은 경계선에서 사람마다 답이 갈리지만, **「`layout.js` 가 이걸 그리는가」는 파일을 열면 나온다.**
- 자리는 셋이다 — **layout 이 그리면** `components/layout/`, **그 화면 갈래 안에서만 쓰면** `app/<갈래>/_components/`, **갈래 밖에서도 쓰면** `components/`.
- **「몇 곳에서 쓰나」로 묻지 않고 「어느 갈래 밖에서도 쓰나」로 묻는다.** 만들기 화면과 고치기 화면이 같은 폼을 쓰는 것은 2곳이지만 공용이 아니다 — 그 갈래 밖에서는 아무도 안 쓴다. `_components/` 는 페이지 하나가 아니라 **갈래에 딸린다.**
- **올리기만 하고 내리지 않는다.** 두 번째 갈래에서 쓰게 되면 그때 `components/` 로 올린다. 「일단 공용에 두고 안 쓰이면 내린다」는 반대로 하지 않는다 — 내리는 일은 급하지 않아 아무도 안 하고 공용 폴더만 커진다.
- **모든 페이지에 뜨는 것을 페이지가 손으로 import 하지 않는다.** 새 페이지에서 까먹으면 그 페이지만 빠진다 — 실제로 푸터가 13곳 중 9곳에서 빠져 있었다.
- 밑줄로 시작하는 폴더(`_components`)는 **라우팅에서 빠진다.** 페이지 전용 컴포넌트를 그 페이지 옆에 두는 Next.js 공식 방식이다.
- **대부분에 뜨는데 하나만 빼야 하면 route group 으로 layout 을 나눈다.** 그룹 이름은 `(with-cta)` 같은 예외 표시가 아니라 `(browse)` · `(form)` 처럼 **성격**으로 짓는다 — 그래야 같은 성격이 늘 때 넣기만 하면 되고 예외 목록이 안 생긴다.
- **컴포넌트가 `usePathname()` 으로 경로를 보고 자기를 숨기지 않는다.** 그 목록을 사람이 관리하게 되고 페이지가 늘 때 까먹으면 어긋난다.
- 다른 그룹에 **같은 URL** 이 생기면 에러다. 다른 URL 이면 같은 경로 아래라도 그룹이 갈려도 된다(`/inquiries``/inquiries/new`).
- **기기별로 다르게 보여야 하면 layout 은 전부 그리고 CSS 가 가른다.** 정적 export 면 서버가 화면 크기를 모른다 — JS 로 재어 조건부로 그리면 첫 화면이 깜빡이고 JS 가 꺼지면 아예 안 뜬다. **안 보이는 것도 HTML 에 실리지만 레이아웃 조각은 몇 개 안 되므로 감수한다.** 목록이 긴 것은 이 방식을 쓰지 않는다.

자신만의 철학을 만들어가는 중입니다.
최상단으로 이동했습니다!
확대 이미지

댓글남기기