랜딩 페이지 설계: 빠른 첫 화면과 정확한 분기, 둘 다 잡기
랜딩 페이지는 사용자가 서비스를 처음 만나는 지점이다.
그래서 두 가지 요구를 동시에 만족해야 한다.
- 최대한 빠르게 보여야 한다.
- CTA 클릭 시 사용자 상태에 맞는 정확한 목적지로 이동해야 한다.
문제는 이 두 요구가 자주 충돌한다는 점이다.
랜딩에서 바로 세션을 조회해 분기하면 목적지 결정은 쉬워지지만, 랜딩을 정적으로 유지하기 어려워진다.
반대로 랜딩을 완전 정적으로 두면 CTA 이후 분기 로직을 별도로 설계해야 한다.
해결 아이디어: CTA는 무조건 /me로 보낸다
핵심은 책임 분리다.
- 랜딩(
/)은 정적 UI만 담당 /me는 서버 리다이렉트 전용 엔드포인트로 동작
이렇게 하면 랜딩은 끝까지 빠르게 유지하면서, 사용자 상태 기반 분기는 /me 한 곳에서 일관되게 처리할 수 있다.
"use client";
import Link from "next/link";
import { useRouter } from "next/navigation";
export default function CTAButton() {
const router = useRouter();
return (
<Link
href="/me"
prefetch={false}
onMouseEnter={() => router.prefetch("/me")}
>
Start for free
</Link>
);
}
/me에서 목적지를 단일 책임으로 처리
사용자가 CTA를 누르면 항상 /me로 이동하고, /me에서 세션/온보딩/핸들을 순차 판별해 최종 리다이렉트한다.
- 세션 없음 →
/sign-in - 세션 있음 + 온보딩 미완료 →
/onboarding - 온보딩 완료 + 정상 핸들 →
/${handle} - 핸들 없음/비정상 →
/onboarding
import { redirect } from "next/navigation";
export default async function MePage() {
const session = await getSession();
if (!session) redirect("/sign-in");
const onboardingComplete = isOnboardingComplete(session.user.userMetadata);
if (!onboardingComplete) redirect("/onboarding");
const primaryPage = await findPrimaryPageHandleByUserId(session.user.id);
if (!primaryPage?.handle?.startsWith("@")) {
redirect("/onboarding");
}
redirect(`/${primaryPage.handle}`);
}
이 구조의 핵심은 명확하다.
랜딩 렌더링과 인증 기반 목적지 결정을 분리해, 각각의 관심사를 섞지 않는다.
프리패치 전략 개선
Next.js Link는 기본 자동 prefetch를 수행한다.
하지만 /me는 단순 정적 라우트가 아니라 세션 조회와 분기 판단이 있는 서버 페이지다.
자동 prefetch를 그대로 두면 사용자가 CTA를 누르지 않아도 인증 관련 선행 요청이 발생할 수 있다.
그래서 다음 전략이 더 합리적이다.
- 기본 prefetch 비활성화 (
prefetch={false}) - 클릭 가능성이 높아지는 시점(예: hover)에만 수동 prefetch
이렇게 하면 불필요한 선행 요청을 줄이면서도, 실제 클릭 직전 체감 속도는 유지할 수 있다.
트레이드오프와 운영 포인트
이 패턴에는 트레이드오프도 있다.
- 라우팅 홉 증가:
/ → /me → 최종 경로 - 인증/온보딩 분기 로직이
/me에 집중 - 따라서
/me의 안정성과 테스트가 중요
그럼에도 랜딩 성능(정적 유지)과 정책 관리 일관성(분기 단일화)을 함께 확보한다는 점에서 충분히 합리적인 선택이다.
결론
CTA → /me 패턴은 “빠른 랜딩”과 “정확한 목적지 분기”의 충돌을 풀기 위한 실용적인 구조다.
랜딩은 정적으로 가볍게 유지하고, 상태 기반 의사결정은 /me에서 중앙집중 처리한다.
결과적으로 성능, 유지보수성, 정책 일관성을 동시에 가져갈 수 있다.