Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion llm-wiki/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@

## 최근 산출물

-
- [FAQ 랜딩페이지 추가 구현 설계서](output/2026-08-18-faq-landing-page-implementation-plan.md)
- [클라이언트 Supabase 호출을 app/api로 이관하는 구현 설계서](output/2026-08-14-github-issue-170-supabase-client-to-app-api-migration-plan.md)

2 changes: 2 additions & 0 deletions llm-wiki/log.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
| 2026-08-13 | GitHub 이슈 #193을 `raw/2026-08-13-github-issue-193-llm-wiki-setup.md`에 저장 | 작업 기획서 원본 보존 | - |
| 2026-08-13 | 첫 `wiki/` 문서 `llm-wiki-background-and-structure.md` 작성 | 배경, 해결 범위, 구조, 다음 질문 정리 | 이슈 #193 "후속 문서 작성 및 에이전트 연동 범위 정리" 작업 미완료 |
| 2026-08-13 | GitHub 이슈 #195을 `raw/2026-08-13-github-issue-195-naver-search-advisor.md`에 저장 | 네이버 서치어드바이저 등록 작업 기획서 원본 보존 | 아직 `wiki/` 정리 문서 미작성 |
| 2026-08-14 | `src/lib/**` 전수 조사 후 `output/2026-08-14-github-issue-170-supabase-client-to-app-api-migration-plan.md` 작성 | 이관 대상 28파일 39함수 확정, Route Handler 22개 구조와 API 명세 정리, 후속 이슈 8건 도출 | `getInviteFriendList` 호출부 확인, 왕복 지연 실측 |
| 2026-08-18 | 랜딩페이지와 검색 관련 코드 조사 후 `output/2026-08-18-faq-landing-page-implementation-plan.md` 작성 | FAQ 섹션, 공용 콘텐츠 원본, 구조화 데이터와 플레이wright 검증 범위 설계 | 최종 문항과 답변, 콘텐츠 목업, 펼침 방식 확인 |

Large diffs are not rendered by default.

216 changes: 216 additions & 0 deletions llm-wiki/output/2026-08-18-faq-landing-page-implementation-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
# FAQ 랜딩페이지 추가 구현 설계서

## 한 문장 요약

공개 랜딩페이지에 서비스별 구독 공유 정산 질문을 다루는 FAQ 섹션을 추가하고, 화면 콘텐츠와 구조화 데이터가 어긋나지 않도록 같은 데이터 원본을 사용하여 서비스명과 엔빵을 조합한 검색어의 노출 기반을 넓힌다.

## 근거

- 원천 자료: 사용자 제공 노션 요약과 저장소 코드 직접 조사 (`src/app/page.tsx`, `src/components/landing/**`, `src/lib/jsonLd.ts`, `e2e/landing.spec.ts`)
- 확인 날짜: 2026-08-18
- 자료 성격: 기획 요약, 코드
- 관련 문서: [llm-wiki 배경과 구조](../wiki/llm-wiki-background-and-structure.md)
- 관련 이슈: [GitHub Issue #200](https://github.com/andbread/Andbread_Frontend/issues/200)

---

## 1. 배경과 목적

### 1.1 현재 상태

공개 랜딩페이지 배포 뒤 검색 노출 발생일은 14%에서 81%로, 일평균 검색 노출은 0.14에서 1.90으로 늘었다. 현재 확인된 노출 키워드 중에서는 `넷플릭스 엔빵`의 노출이 가장 높아 `서비스명 + 엔빵` 형태의 검색 수요가 있음을 확인했다.

현재 랜딩페이지는 엔빵의 문제 정의, 해결 방식, 핵심 기능, 사용 방법과 시작하기 유도 영역으로 구성되어 있다. 넷플릭스, 유튜브 프리미엄, 왓챠 등 서비스명은 소개 문구에 일부 포함되어 있지만, 사용자가 검색하는 구체적인 질문과 답변을 다루는 영역은 없다.

### 1.2 이번 작업의 목표

- 공개 랜딩페이지에 FAQ 콘텐츠를 추가한다.
- 서비스명과 엔빵을 조합한 검색어를 자연스럽게 포함할 수 있는 콘텐츠 기반을 마련한다.
- 질문과 답변을 검색 로봇과 보조 기술이 이해할 수 있는 의미 구조로 제공한다.
- 화면에 표시하는 FAQ와 FAQ 구조화 데이터가 같은 내용을 유지하도록 한다.
- 기존 랜딩페이지의 모바일 중심 배치, 색상, 간격, 스크롤 진입 효과를 따른다.

### 1.3 이번 작업의 비목표

- FAQ 문항과 답변의 최종 문구를 이 설계서에서 확정하지 않는다. 최종 콘텐츠는 별도 목업을 전달받은 뒤 확정한다.
- 목업에 없는 FAQ 검색, 분류, 별도 상세 페이지, 관리자 편집 기능은 만들지 않는다.
- 랜딩페이지의 기존 섹션이나 전체 정보 구조를 다시 설계하지 않는다.
- 검색 노출 순위나 노출량의 개선을 완료 조건으로 삼지 않는다. 검색엔진 반영 지연과 작은 측정 모수 때문에 이번 구현만으로 인과관계를 확정할 수 없다.
- 메타데이터의 전면 개편이나 별도 검색 최적화 작업은 진행하지 않는다.

---

## 2. 코드베이스 확인 결과

### 2.1 랜딩페이지 구성

- `src/app/page.tsx`는 서버 컴포넌트이며 모든 랜딩 섹션을 위에서 아래로 직접 조합한다.
- 반복 콘텐츠는 `painCards`, `solutionPoints`, `featureCards`, `steps`와 같은 정적 배열에서 렌더링한다.
- 각 섹션은 `px-24`, `py-48` 또는 `py-54`를 중심으로 구성하고, 배경색을 번갈아 사용한다.
- 섹션 제목은 페이지 내부의 `SectionHeading`을 재사용한다.
- 화면 진입 효과는 `src/components/landing/RevealOnScroll.tsx`가 담당한다. 이 파일만 클라이언트 컴포넌트이고 나머지 랜딩 콘텐츠는 서버에서 렌더링된다.
- 마지막 시작하기 영역 바로 앞이 FAQ를 추가하기에 자연스러운 위치로 보이지만, 최종 위치와 배경색은 목업 확인이 필요하다.

### 2.2 검색 관련 구성

- 랜딩페이지 메타데이터는 `src/lib/seo.ts`의 `createPageMetadata`를 사용한다.
- `src/lib/jsonLd.ts`의 `landingPageJsonLd`는 현재 `Organization`, `WebSite`, `WebApplication` 정보를 제공한다.
- `src/components/seo/JsonLdScript.tsx`가 구조화 데이터를 안전하게 직렬화하여 페이지에 삽입한다.
- FAQ 구조화 데이터는 현재 없다.

### 2.3 테스트 구성

- `e2e/landing.spec.ts`에 랜딩페이지 제목, 주요 제목과 로그인 링크를 확인하는 플레이wright 테스트가 있다.
- FAQ 추가 시 같은 테스트 파일에 FAQ 노출과 상호작용을 검증하는 것이 기존 범위에 가장 가깝다.

---

## 3. 구현 방향

### 3.1 FAQ 데이터 원본을 하나로 유지한다

질문과 답변 목록은 타입이 있는 정적 데이터로 정의하고 화면과 구조화 데이터가 함께 사용한다. 이렇게 하면 문구 수정 시 화면에는 바뀌었지만 구조화 데이터에는 이전 문구가 남는 문제를 막을 수 있다.

데이터를 `src/app/page.tsx` 안에 둘지 `src/components/landing/FaqSection.tsx`와 가까운 별도 파일에 둘지는 최종 컴포넌트 경계를 정할 때 결정한다. 화면과 `src/lib/jsonLd.ts`가 함께 가져와야 한다면 순환 참조를 피할 수 있는 공용 모듈로 분리한다. 정확한 파일 위치는 `확인 필요`다.

초안으로 전달된 다음 네 문항은 콘텐츠 검토를 위한 참고 자료로만 사용한다.

1. 엔빵은 어떻게 시작하나요?
2. 넷플릭스 구독료는 어떻게 나눠서 정산하나요?
3. 유튜브 프리미엄 가족 요금제는 어떻게 정산하나요?
4. 왓챠나 티빙도 구독 공유 정산이 가능한가요?

최종 질문, 답변, 표기 방식은 목업을 전달받은 뒤 확정한다. 서비스 정책이나 실제 지원 범위를 확인하지 않은 답변을 추측해서 작성하지 않는다.

### 3.2 기존 랜딩 컴포넌트 패턴을 따른다

`src/components/landing/FaqSection.tsx`를 추가하고 `src/app/page.tsx`에서 기존 섹션과 같은 방식으로 조합한다. FAQ 섹션은 다음 원칙을 따른다.

- `SectionHeading`과 `RevealOnScroll`을 재사용할 수 있도록 필요한 범위만 조정한다.
- 기존 최대 너비와 모바일 우선 배치를 유지한다.
- 제목과 답변은 의미에 맞는 제목과 본문 요소로 렌더링한다.
- 목업이 펼침과 접힘을 요구하면 키보드와 보조 기술로 조작 가능한 요소를 사용하고 상태를 알 수 있는 속성을 제공한다.
- 목업이 모든 답변을 펼쳐 보이는 형태라면 불필요한 클라이언트 상태를 추가하지 않는다.

`SectionHeading`은 현재 `src/app/page.tsx` 내부에 있어 새 컴포넌트에서 바로 재사용할 수 없다. FAQ만을 위해 공용 컴포넌트로 옮길지, FAQ 안에서 같은 시각 규칙을 적용할지는 목업과 중복 정도를 본 뒤 최소 변경안을 선택한다. 이 판단은 `확인 필요`다.

### 3.3 FAQ 구조화 데이터를 함께 제공한다

기존 `landingPageJsonLd`의 `@graph`에 `FAQPage` 항목을 추가하고, 화면에 실제 표시되는 최종 질문과 답변만 `mainEntity`에 넣는다. 구조화 데이터가 검색 결과의 별도 표시를 보장하지는 않지만, 페이지 콘텐츠의 의미를 기계가 이해할 수 있는 형태로 제공한다.

구조화 데이터와 화면이 같은 FAQ 데이터 원본을 사용하게 하고, 숨겨진 키워드나 화면에 없는 답변은 넣지 않는다. 문항이 확정되기 전에는 임시 문구로 구조화 데이터를 배포하지 않는다.

### 3.4 검토한 대안

| 대안 | 판단 | 이유 |
|---|---|---|
| FAQ를 `src/app/page.tsx`에 모두 직접 작성한다 | 선택하지 않는다 | 페이지 파일이 이미 여러 섹션과 정적 데이터를 포함하고 있어 FAQ의 표시와 상호작용까지 추가하면 책임이 더 커진다 |
| FAQ를 별도 경로로 만든다 | 선택하지 않는다 | 이번 목표는 기존 공개 랜딩페이지의 검색 콘텐츠를 보강하는 것이며 별도 페이지 요구사항이 없다 |
| 구조화 데이터에만 FAQ를 추가한다 | 선택하지 않는다 | 사용자에게 보이지 않는 콘텐츠를 구조화 데이터에만 넣으면 화면과 데이터가 불일치한다 |
| 화면과 구조화 데이터의 문항을 각각 관리한다 | 선택하지 않는다 | 콘텐츠가 바뀔 때 두 위치가 어긋날 위험이 있다 |

---

## 4. 작업 분리

이번 범위는 한 이슈와 한 풀 리퀘스트로 구현 가능한 크기다. 목업과 최종 문항이 전달된 뒤 아래 순서로 진행한다.

### Task 1. 목업과 콘텐츠 확정

- 전달받은 목업에서 섹션 위치, 배경색, 간격, 질문 항목의 표시 방식과 펼침 동작을 확인한다.
- 최종 질문과 답변이 실제 엔빵 기능 및 정책과 맞는지 확인한다.
- 목업과 초안 사이에 차이가 있으면 목업과 별도 확정 내용을 기준으로 범위를 기록한다.

### Task 2. FAQ 데이터와 섹션 컴포넌트 추가

- 질문과 답변의 타입과 정적 데이터 원본을 정의한다.
- `src/components/landing/FaqSection.tsx`를 추가한다.
- 최종 목업에 따라 정적 목록 또는 접근 가능한 펼침 목록으로 구현한다.
- 기존 `RevealOnScroll`과 디자인 토큰을 재사용한다.

### Task 3. 랜딩페이지에 FAQ 섹션 배치

- `src/app/page.tsx`에 FAQ 섹션을 추가한다.
- 기존 섹션 순서와 시작하기 흐름이 유지되는지 확인한다.
- `SectionHeading` 재사용을 위한 변경이 필요하다면 랜딩 영역 안에서 최소 범위로만 조정한다.

### Task 4. FAQ 구조화 데이터 연결

- `src/lib/jsonLd.ts`의 랜딩페이지 그래프에 `FAQPage` 정보를 추가한다.
- 화면과 구조화 데이터가 같은 최종 질문과 답변을 사용하게 한다.
- 생성된 제이슨 엘디가 화면에 없는 내용이나 임시 문구를 포함하지 않는지 확인한다.

### Task 5. 검증

- `e2e/landing.spec.ts`에 FAQ 제목과 최종 문항 노출을 확인하는 시나리오를 추가한다.
- 펼침 방식이면 키보드 또는 클릭으로 답변을 열고 닫는 동작을 확인한다.
- 기존 시작하기 링크와 랜딩 섹션이 그대로 동작하는지 확인한다.
- `npm run lint`, `npm run build`, 영향받은 플레이wright 테스트를 실행한다.

---

## 5. 영향 범위

### 변경 예정

- `src/app/page.tsx`: FAQ 섹션 배치
- `src/components/landing/FaqSection.tsx`: FAQ 화면 구성 요소 추가
- FAQ 정적 데이터 모듈: 정확한 위치는 확인 필요
- `src/lib/jsonLd.ts`: FAQ 구조화 데이터 추가
- `e2e/landing.spec.ts`: FAQ 노출과 동작 검증 추가

### 변경하지 않음

- 로그인 뒤 서비스 화면과 인증 흐름
- Supabase 스키마, 데이터, 인증, 보안 정책
- 상태 관리 저장소와 서버 통신
- 기존 메타데이터 전반과 사이트맵 설정
- 기존 랜딩페이지 문구와 기능 카드의 내용

---

## 6. 제약사항

- 콘텐츠 목업과 문항 최종본을 받기 전에는 실제 구현을 시작하지 않는다.
- 서비스명과 키워드를 반복하기 위해 부자연스러운 문장을 만들지 않는다.
- 질문과 답변은 실제 제공 기능과 정책을 넘어 추측하지 않는다.
- FAQ 구조화 데이터에는 화면에서 사용자가 확인할 수 있는 내용만 포함한다.
- 접힘 상태를 사용하더라도 서버가 질문과 답변 본문을 렌더링해 검색 로봇과 자바스크립트를 쓰지 않는 환경에서도 콘텐츠를 읽을 수 있어야 한다.
- 기존 랜딩페이지의 공개 접근, 로그인 링크와 마지막 시작하기 흐름을 유지한다.
- 새 의존성은 추가하지 않는다.

---

## 7. 리스크와 대응

| 리스크 | 영향 | 대응 |
|---|---|---|
| 최종 문항과 답변이 미확정이다 | 추측한 서비스 정책이나 목업과 다른 화면을 구현할 수 있다 | 목업과 확정 문구를 받은 뒤 Task 1을 완료하고 구현한다 |
| 검색 효과를 짧은 기간에 판단하기 어렵다 | 구현 직후 성과를 잘못 해석할 수 있다 | 검색 노출은 별도 관찰 지표로 두고 구현 완료 조건과 분리한다 |
| 화면과 구조화 데이터가 어긋날 수 있다 | 검색 로봇이 실제 화면과 다른 내용을 읽을 수 있다 | 같은 타입이 있는 데이터 원본에서 두 출력을 만든다 |
| 펼침 목록의 접근성이 빠질 수 있다 | 키보드 및 보조 기술 사용자가 답변을 이용하기 어렵다 | 목업이 펼침 방식을 요구하면 의미 요소와 상태 속성을 쓰고 동작 테스트를 추가한다 |
| 클라이언트 컴포넌트 범위가 커질 수 있다 | 불필요한 자바스크립트가 늘고 서버 렌더링 경계가 흐려질 수 있다 | 상호작용이 필요한 최소 구성 요소만 클라이언트로 두고 정적 형태면 서버 컴포넌트로 유지한다 |
| 긴 답변이 모바일 화면 흐름을 해칠 수 있다 | 마지막 시작하기 영역 도달성과 가독성이 떨어질 수 있다 | 목업 기준으로 줄바꿈과 간격을 확인하고 320픽셀부터 600픽셀 범위에서 검증한다 |

---

## 8. 완료 조건

- 확정된 FAQ 질문과 답변이 공개 랜딩페이지에 표시된다.
- FAQ 섹션이 전달받은 목업과 기존 랜딩페이지 스타일을 따른다.
- 상호작용이 있다면 마우스, 터치와 키보드로 사용할 수 있고 상태가 보조 기술에 전달된다.
- 화면 FAQ와 `FAQPage` 구조화 데이터의 질문 및 답변이 일치한다.
- 기존 시작하기 링크와 랜딩페이지 주요 콘텐츠가 정상 동작한다.
- 랜딩페이지 플레이wright 테스트가 FAQ를 포함해 통과한다.
- `npm run lint`와 `npm run build`가 통과한다.

---

## 확인 필요

- 최종 FAQ 질문과 답변 문구
- FAQ 콘텐츠 목업과 섹션의 정확한 위치 및 배경색
- 답변을 항상 펼쳐 둘지, 한 항목씩 또는 여러 항목을 펼칠 수 있게 할지
- 질문 항목에 사용할 아이콘과 열림 및 닫힘 상태 표현
- `SectionHeading`을 별도 파일로 옮겨 재사용할지 FAQ 안에서 최소한으로 구성할지
- FAQ 데이터 원본의 파일 위치
23 changes: 23 additions & 0 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import Image from 'next/image'
import type { ReactNode } from 'react'
import Icon, { type IconType } from '@/components/common/icon/Icon'
import NbreadsImage from '@/components/common/nbreadImage/NbreadsImage'
import FaqAccordionItem from '@/components/landing/FaqAccordionItem'
import RevealOnScroll from '@/components/landing/RevealOnScroll'
import JsonLdScript from '@/components/seo/JsonLdScript'
import NbreadLogo from '@/assets/logo/nbread-logo-text.svg'
import { faqItems } from '@/lib/faq'
import { landingPageJsonLd } from '@/lib/jsonLd'
import { createPageMetadata } from '@/lib/seo'

Expand Down Expand Up @@ -352,6 +354,27 @@ export default function LandingPage() {
</RevealOnScroll>
</section>

<section className="bg-primary-100 px-24 py-54">
<RevealOnScroll>
<SectionHeading eyebrow="자주 묻는 질문" title="엔빵이 궁금하신가요?" />
<p className="mt-28 break-keep text-[16px] leading-[26px] text-gray-600">
가장 많이 물어보시는 질문을 모았어요.
</p>
</RevealOnScroll>

<div className="mt-28 flex flex-col gap-8">
{faqItems.map((item, index) => (
<RevealOnScroll key={item.question} delay={index * 60}>
<FaqAccordionItem
question={item.question}
answer={item.answer}
defaultOpen={index === 0}
/>
</RevealOnScroll>
))}
</div>
</section>

<section className="bg-background px-24 py-48 text-center">
<RevealOnScroll>
<div className="flex justify-center">
Expand Down
10 changes: 10 additions & 0 deletions src/assets/icons/angle-down.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/icons/angle-up.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading