2026-09-10: 설명과 코드 예시를 보완했습니다. 아래 예시는 글의 설계 의도를 전달하기 위한 것이며, 원 프로젝트에 반영된 변경 내역과는 구분합니다.
↑ ↑ ↓ ↓ ← → ← → B A
이 순서를 보면 손부터 움직이는 사람이 있을 것이다. 게임 속 비밀 코드를 웹에도 살짝 옮겨봤다. 정해진 키 순서를 입력하면 콜백이 실행되고, 평소에는 보이지 않던 메시지가 나타난다. 없어도 서비스는 잘 돌아간다. 그래서 넣어보고 싶은 기능이기도 하다.
프로젝트 저장소
발견하는 재미까지
시퀀스를 Base64로 바꾸거나 개발자 도구의 크기를 추측한다고 관리자 권한을 보호할 수는 없다. Base64는 디코딩할 수 있는 인코딩이고, 이스터에그는 발견하는 재미를 위한 장치다. MDN btoa
민감한 작업의 인증과 권한은 서버에서 확인해야 한다. 이 예시는 메시지, 애니메이션, 개발 환경의 상태 표시처럼 공개되어도 되는 동작을 대상으로 한다.
핵심 구현
이전 예시의 난독화와 디버거 탐지를 덜어내고 입력 비교와 구독 해제에 집중했다.
export function createEasterEgg(
target: HTMLElement,
callback: () => void,
keySequence: readonly string[],
): () => void {
const sequence = [...keySequence];
if (sequence.length === 0) return () => {};
const recent: string[] = [];
const handleKeyDown = (event: KeyboardEvent) => {
if (event.isComposing || event.repeat) return;
if (event.target instanceof Element &&
event.target.closest('input, textarea, [contenteditable]')) return;
recent.push(event.key);
if (recent.length > sequence.length) recent.shift();
if (recent.length === sequence.length &&
sequence.every((key, index) => key === recent[index])) {
recent.length = 0;
callback();
}
};
target.addEventListener('keydown', handleKeyDown);
return () => target.removeEventListener('keydown', handleKeyDown);
}
최근 입력을 시퀀스 길이만큼 보관하므로, 틀린 입력 뒤에 정답 시퀀스를 이어 입력해도 다시 감지할 수 있다. 입력 필드와 조합 중인 키는 건드리지 않도록 제외했다.
const dispose = createEasterEgg(
document.body,
() => alert('이스터에그를 찾았습니다!'),
['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown',
'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a'],
);
// 화면이나 기능이 정리되는 시점에 호출한다.
// dispose();
React에서 사용한다면 effect의 cleanup으로 dispose를 반환하면 된다. 키보드 입력만을 다루는 예시이며 모바일 접근이 필요하면 별도의 진입 방법을 제공해야 한다.
누군가 키를 눌러 메시지를 발견하면 이 코드는 제 역할을 한 셈이다. 개발자 도구까지 잘 쓰는 사람에게는 이 정도 추리가 어렵지 않을 것이다.
찾았다고 관리자 권한까지 주지는 말자. 대신 “여기까지 찾아오셨군요”라는 인사 정도는 남겨둘 수 있다. 그 사람도 동료 개발자라면, 서로 할 이야기가 제법 있을 테니까.
Assisted by AI
© uiwwsw · 본인 소유의 글·이미지에 대한 무단 복제·재게시를 허용하지 않습니다. 개인 열람·원문 링크 공유·검색 색인과 제한적인 미리보기는 허용합니다. 법령상 이용 예외, 기존 이용 허락, 코드·제삼자 자료의 기존 라이선스는 유지합니다. 콘텐츠 이용 안내