RSS
프론트엔드

iframe 안의 CTA 버튼: 창 안에서는 문의 링크를 숨기는 규칙

작성자
듀오랩스 대표·4분 읽기

듀오랩스의 데모 앱들은 두 곳에서 창으로 열립니다. 하나는 홈페이지의 데모 모달이고, 다른 하나는 브라우저 안에서 도는 웹 데스크톱(os.duolabs.co.kr)의 창입니다. 둘 다 iframe입니다.

데모 앱에는 "듀오랩스에 제작 문의" 버튼이 있습니다. 앱을 단독으로 열었을 때는 당연히 있어야 하는 버튼입니다. 그런데 이 앱이 창 안에서 열리면 이 버튼이 이상하게 동작했습니다. 홈페이지의 모달 안에서 누르면 모달 안에 홈페이지가 한 번 더 떴습니다. 웹 데스크톱의 창 안에서 누르면 웹 데스크톱 탭이 통째로 홈페이지로 넘어가 버렸습니다.

앱마다 알아서 처리했던 결과

형제 앱을 모아 보니 창 안에서의 동작이 세 가지로 갈려 있었습니다. 아홉 곳은 창 안에서 버튼을 숨겼습니다. 여섯 곳은 링크에 target="_top"을 달아 바깥 창 전체를 이동시켰습니다. 한 곳은 창 안에서 그대로 이동했습니다.

_top을 단 앱들은 나름의 이유가 있었습니다. 창 안에 홈페이지가 겹쳐 뜨는 것보다는 바깥으로 나가는 편이 낫다는 판단입니다. 그런데 웹 데스크톱에서는 이것이 가장 나쁜 결과였습니다. 사용자가 창 여러 개를 열어 두고 이것저것 보던 중에 버튼 하나를 누르면, 열어 둔 창이 전부 사라지고 탭이 홈페이지로 바뀝니다.

창 안에서도 보이게 하자는 첫 계획

처음에는 창 안에서도 버튼을 살리는 방향으로 설계했습니다. 웹 데스크톱이 창 주소에 표시를 붙이고, 앱 안의 버튼은 누르면 postMessage로 웹 데스크톱에 "홈페이지 창을 하나 열어 달라"고 부탁하는 방식입니다. 탭을 빼앗지 않고 새 창으로 홈페이지를 띄울 수 있습니다. 설계 문서에 규칙까지 적었습니다.

계획을 버린 이유

이 계획은 하루 만에 폐기했습니다. 질문을 바꿔 보니 답이 달라졌습니다. 창 안에서 이 앱을 보고 있는 사람은 누구인가. 홈페이지의 데모 모달을 연 사람이거나 웹 데스크톱에 들어온 사람입니다. 둘 다 이미 듀오랩스에 와 있는 사람입니다.

제작 문의 버튼은 다른 곳에서 우리 앱을 발견한 사람을 우리에게 데려오는 문입니다. 이미 우리 집 안에 있는 사람에게 우리 집 주소를 알려 주는 버튼은 필요가 없습니다. 창 안에서 보이게 하려고 postMessage 규약을 설계하는 것은, 없어도 되는 버튼을 위해 두 앱 사이의 약속을 하나 더 만드는 일이었습니다.

그래서 규칙을 하나로 정했습니다. 창 안에서는 CTA를 보이지 않는다. 예외를 두지 않습니다.

판정은 한 줄, 빠뜨릴 수 없게

창 안인지는 이렇게 판정합니다.

const embedded = window.self !== window.top;

바깥 창이 다른 출처라서 window.top의 내용에 접근할 수 없어도, 이 비교 자체는 됩니다. 비교가 거짓이면 창 안입니다.

주의할 점은 서버 렌더링입니다. 서버에는 window가 없으니 서버에서 버튼을 그리고 브라우저에서 지우면, 창 안에서 버튼이 잠깐 보였다가 사라지는 깜빡임이 생깁니다. 그래서 서버에서는 그리지 않고, 브라우저에서 최상위 창인 것이 확인된 뒤에만 그립니다. 단독으로 연 페이지에서는 버튼이 한 박자 늦게 나타나지만, 창 안에서 깜빡이는 것보다는 낫다고 판단했습니다.

이 판정을 각 앱이 직접 쓰게 두면 언젠가 한 앱이 빠뜨립니다. 앞의 세 가지 동작이 갈린 것도 앱마다 따로 처리했기 때문입니다. 그래서 CTA 컴포넌트 자체가 이 판정을 기본으로 품게 했습니다. 앱은 CTA를 넣기만 하고, 창 안에서 숨는 것은 컴포넌트가 알아서 합니다.

한 번 더 확인하게 된 것

규칙을 정한 뒤, 한 앱의 바닥 링크에 target="_top"을 넣었다가 다시 뺀 일이 있었습니다. 그 사이에 웹 데스크톱 쪽 동작이 바뀌었기 때문입니다. 창 안의 링크는 창 밖의 동작에 기대고 있어서, 바깥이 바뀌면 안쪽의 올바른 답도 바뀝니다. 창 안에서 링크를 아예 보이지 않게 한 규칙은 이런 흔들림에서도 자유롭습니다. 보이지 않는 링크는 바깥이 어떻게 바뀌어도 틀리지 않습니다.

이 게시글 공유하기

마지막 수정:

공유하실 때는 출처(Duolabs)와 원문 주소를 표시해 주세요.