좋은 웹사이트는 화려한 코드가 아니라 "왜 이렇게 했는가"의 누적입니다. 아래 17강은 모두 이 사이트에서 실제로 일어난 일이고, 각 강은 「실제 과업 → 핵심 개념 → 교훈」으로 읽습니다. 바로 아래 마인드맵의 강 제목을 누르면 해당 강으로 바로 이동합니다.
한눈에 보기 — 구조 마인드맵
강 제목을 누르면 해당 강으로 이동합니다.
배우는 웹 만들기
Part 1 · 구조와 설계의 결정
1강. 한 페이지로 다 짓기 — SPA 오버레이 구조
실제 과업. 이 사이트는 index.html 하나에 모든 화면이 들어 있습니다. 메뉴를 누르면 script.js가 showSubPageFull()로 해당 화면을 통째로 그려 넣어요.
핵심 개념. SPA(Single Page Application) — 페이지를 새로 불러오지 않고 자바스크립트가 화면을 갈아끼웁니다.
교훈. 전환이 매끄럽지만 각 화면에 고유 주소가 없어 검색·공유에 약합니다. 이 약점이 5강의 복선입니다.
2강. 세 가지 방식으로 배우는 다국어(i18n)
실제 과업. 한·영·중 3개 국어. 홈은 태그에 data-i18n="키", 서브페이지는 함수 안 L 라벨 객체, 50개 사례는 원본을 두고 culturalArchiveZh.js·En.js 번역 맵을 곁에 붙였습니다.
핵심 개념. 텍스트를 코드에서 떼어내기. 규모가 커질수록 분리 수준을 높입니다 — 속성 → 객체 → 별도 파일.
교훈. 원본은 절대 덮어쓰지 않고, 번역은 곁에 둡니다. 한 언어 수정이 다른 언어를 깨지 않게.
3강. 상태와 다시 그리기
실제 과업. 서브페이지를 열어둔 채 언어를 바꿔도 화면이 그대로인 버그 → 현재 화면 그리는 함수를 _activeSubPageRender에 기억해두고 언어가 바뀌면 다시 호출.
핵심 개념. 화면은 데이터(상태)의 결과물. 상태가 바뀌면 다시 그린다.
교훈. 다시 그리면 폼 입력이 초기화되는 부작용도 따라온다. 모든 선택엔 대가가 있다.
4강. 길을 만드는 일 — 정보구조(IA)와 내비게이션
실제 과업. 메뉴에 "교육자료" 한 줄 추가. "문화공간 재생"은 새로 안 만들고 기존 50개 아카이브로 딥링크(#cultural-archive) 재활용.
핵심 개념. 사용자가 길을 찾는 지도(IA)와 자산 재사용.
교훈. 새로 만들기 전에, 이미 가진 것을 연결할 수 없는지 먼저 본다.
5강. 콘텐츠는 페이지로 — SPA의 한계 넘기
실제 과업. 교육 콘텐츠는 오버레이가 아니라 실제 파일 /learn/로. 지금 이 페이지가 그 결정의 산물.
핵심 개념. 관심사 분리. 영업과 교육은 목적이 다르니 구현도 다르게.
교훈. 목적이 다르면 그릇도 다르게. 한 방식으로 모든 걸 우겨넣지 않는다.
Part 2 · UX·UI와 인터랙션
6강. UX/UI 원칙 — 이 사이트가 지킨 것들
실제 과업. 일관된 브랜드(딥그린 #3B6259, 본문 Noto Sans KR + 강조 Merriweather), 카드·버튼 스타일 통일, 명확한 피드백(언어 버튼 활성 시 녹색, 카드 호버 시 살짝 떠오름), 시각적 위계(작은 라벨 → 제목 → 본문), 반응형(데스크톱 다열 → 모바일 1열).
핵심 개념. UX는 "사용자가 헤매지 않게", UI는 "그것을 눈으로 분명히". 일관성·피드백·위계·반응형이 기본 4축.
교훈. 한 사례 — 캐러셀 점의 클릭 영역을 키우려 패딩을 줬더니 점이 커져 보였다. 기능 개선이 디자인을 해치면 안 된다(투명 영역으로 해결). 화려함이 아니라 명료함이 UX다.
7강. 아코디언 / 토글 — 접었다 펴기
실제 과업. 고객센터 FAQ를 아코디언으로. 질문 행을 클릭하면 답변 행이 펼쳐지고 아이콘이 "클릭 ↔ 닫기"로 바뀝니다(언어별 텍스트). coFaqToggle()가 답변 행의 표시를 토글.
핵심 개념. 점진적 노출(progressive disclosure) — 긴 정보를 접어두고 필요할 때만 펼쳐 화면을 짧게 유지.
교훈. 한 번에 다 보여주지 않는 것도 친절이다. 선택권을 사용자에게.
8강. 툴팁 — 작은 힌트
실제 과업. 아이콘만 있는 SNS 버튼(인스타·페북·블로그)에 title="Instagram" 처럼 속성을 달아, 마우스를 올리면 이름이 뜨게 했습니다.
핵심 개념. 아이콘이 불명확할 때의 보조 설명. HTML 기본 title 속성만으로 가벼운 툴팁 구현.
교훈. 작은 힌트가 오해를 막는다. 단, 모바일엔 마우스 호버가 없으니 핵심 정보를 툴팁에만 의존하면 안 된다.
9강. 팝업 · 모달 — 흐름을 잠시 멈추기
실제 과업. 입금안내 모달, 할인쿠폰 모달, 연락수단 팝업(cuContactPopup). 배경을 어둡게 덮고(dim) 가운데 박스를 띄우며, 바깥 클릭·닫기 버튼으로 닫고 배경 스크롤은 잠급니다.
핵심 개념. 모달은 흐름을 멈추고 한 가지에 집중시키는 레이어. 강력한 만큼 과용 금지.
교훈. 닫는 길을 항상 명확히(바깥 클릭·X). 실제로 스크립트가 요소보다 먼저 로드돼 버튼을 못 찾던 버그가 있었고 DOMContentLoaded로 해결했다 — 순서가 중요하다.
10강. 고정 퀵 사이드바 — 늘 손 닿는 곳에
실제 과업. 화면 우측에 항상 떠 있는 #quickSidebar(position:fixed) — 프로그램·여행이야기·문의·고객센터·입금안내·카카오·TOP. 좁은 화면(1100px 이하)에선 자동으로 숨깁니다.
핵심 개념. 영구 접근(persistent access) — 자주 쓰는 동작을 늘 같은 자리에 둔다.
교훈. 오버레이가 열리면 앵커 이동이 막혀, "닫고 80ms 뒤 스크롤"하는 quickNavTo()로 우회했다. 편의 기능은 화면을 가리지 않는 선에서.
Part 3 · 기능 연동
11강. 게시판 글쓰기 — 정적 사이트 + 서버리스 함수
실제 과업. 정적 사이트인데 글 저장이 필요. 글쓰기 모달(boardOpenWrite) → boardSubmit()이 BOARD_API(Vercel /api/posts 함수)로 전송하고, 글은 Redis(키-값 저장소)에 보관합니다.
핵심 개념. 정적 호스팅 + 필요한 부분만 서버리스 함수 = JAMstack. 프런트는 정적, 동적인 한 조각만 함수로.
교훈. "정적 사이트라 저장 못 한다"는 옛말. 서버 한 대 없이도 게시판이 돈다.
12강. 카카오 채널 연결
실제 과업. 버튼을 누르면 카카오 오픈채팅(open.kakao.com/...)으로 바로 연결돼 상담이 시작됩니다.
핵심 개념. 외부 서비스 딥링크 — 별도 개발 없이 검증된 상담 채널을 즉시 붙이기.
교훈. 모든 걸 직접 만들지 않는다. 잘 만들어진 채널을 연결하는 것도 설계다.
13강. 카카오 로그인 — 개발자 API 등록부터
실제 과업. 카카오 디벨로퍼스에 앱을 등록하고 JavaScript 키를 발급받아, SDK를 불러온 뒤 Kakao.init(키)로 초기화하고 Kakao.Auth.authorize()로 로그인합니다. 콘솔에 서비스 도메인을 등록해야 동작합니다.
핵심 개념. OAuth 소셜 로그인. 흐름은 "개발자 콘솔에서 앱 등록 → 플랫폼(도메인) 등록 → 키 발급 → 코드 연동".
교훈. 외부 인증은 "콘솔 설정 80% + 코드 20%". 리다이렉트·도메인 등록을 빠뜨리면 코드가 맞아도 안 된다(실제로 겪은 함정). JS 키는 클라이언트에 노출돼도 되지만, 비밀 키는 절대 프런트에 두지 않는다.
Part 4 · 버전관리 · 배포 · 협업
14강. Git · GitHub — 되돌릴 수 있다는 안정감
실제 과업. 모든 코드를 GitHub 저장소에 커밋·push로 기록하고, 같은 저장소를 GitHub Pages로 도메인(sunshinewellness.co.kr)에 서빙합니다. 변경마다 커밋이 남아 언제든 되돌릴 수 있어요.
핵심 개념. 버전관리(이력·되돌리기), 원격 저장소, 그리고 GitHub Pages 정적 호스팅.
교훈. 커밋은 작게 자주, 메시지엔 "왜"를 적는다. 되돌릴 수 있다는 안정감이 과감한 실험을 가능하게 한다.
15강. 보이게 만들기 — SEO 기초
실제 과업. sitemap.xml·robots.txt를 추가하고 페이지마다 title·description·canonical 메타를 달았습니다.
핵심 개념. 검색엔진이 페이지를 발견(크롤링)하고 등록(인덱싱)하는 최소 조건.
교훈. 교육·정보 콘텐츠는 "찾아지는 것"이 가치의 절반. 안 만들면 있어도 없는 페이지.
16강. 배포 파이프라인과 그 함정
실제 과업. push하면 Vercel이 자동 빌드·배포. 단, 커밋 메시지에 "배포"가 있을 때만 빌드하게 막아 폭주를 방지했고, 캐시 문제는 script.js?v=... 뒤 글자를 바꿔(캐시 버스팅) 강제 갱신.
핵심 개념. CI/CD, 캐시, 그리고 한 코드가 두 곳(Vercel·도메인)에 배포될 때의 동기화.
교훈. "내 화면엔 됐는데 안 보여요"의 대부분은 브라우저 캐시이거나, 보고 있는 주소가 배포 대상과 다른 경우다.
17강. 협업의 그림자 — 두 손이 같은 파일을 만질 때
실제 과업. 두 터미널에서 같은 저장소를 동시에 만지다 커밋이 섞이고, 저장 시 린터의 자동수정(CRLF)으로 충돌이 났습니다.
핵심 개념. 동시 편집 충돌과 작고 잦은 커밋의 가치.
교훈. 혼자라도 "한 번에 한 흐름"을 지키면 사고가 줄어든다.
마치며
이 사이트의 모든 결정에는 트레이드오프가 있었습니다. 빠름 대 검색 노출, 일관성 대 유지보수, 즉시성 대 안정성. 그 대가를 의식하고 고른 것 — 그것이 곧 설계입니다. 코드는 도구일 뿐이고, 배워야 할 진짜는 "왜"입니다.
더 읽어보기
Open Design — Anthropic Claude Design을 대체하는 오픈소스 AI 디자인 도구
LLM이 산문이 아닌 '디자인 아티팩트'를 직접 생성하는 흐름과, 우리가 이 사이트를 지을 때 쓴 Claude Code·Vercel·디자인 시스템을 활용해 로컬에서 디자인하는 방식을 소개합니다. (파이토치 한국 사용자 모임 정리글)