전체 글로 돌아가기

[해결] 모바일 웹에서 네이티브 공유창을 여는 방법 (Web Share API 적용기)

모바일 웹 환경에서 navigator.share(Web Share API)를 활용해 앱처럼 OS 고유 공유창을 띄우고 데스크톱 Fallback을 처리하는 방법입니다.

fruit.nxnl.appGoodFruit
WebShareAPIJavaScript모바일웹

[해결] 모바일 웹에서 네이티브 공유창을 여는 방법 (Web Share API 적용기)

한 줄 요약: 웹 환경에서도 앱(App)처럼 스마트폰 OS의 네이티브 공유 시트(공유창)를 호출할 수 있도록 navigator.share (Web Share API)를 적용하고, 지원되지 않는 PC/데스크톱 브라우저 환경에서는 Clipboard API 기반의 복사 fallback을 연결해 호환성을 확보했습니다.

1. 어떤 문제가 발생했나

GoodFruit 사용자가 과일 맛 분석 결과를 친구나 메신저에 전달하려고 할 때, 전통적인 웹 사이트의 공유 방식(URL 주소창 직접 복사, 카카오톡 JS SDK 별도 탑재)은 다음과 같은 문제점이 있었습니다.

  • **사용자 경험의 파편화**: 카카오톡, 라인, 인스타그램, 페이스북, SMS, 이메일 등 사용자가 원하는 공유 매체가 제각각이어서 모든 SNS 버튼을 웹 화면에 채워 넣으면 UI가 지저분해집니다.
  • **카카오톡 SDK의 무거움**: 카카오 SDK script를 로드하면 모바일 웹페이지 초기 로딩 속도(LCP)가 저하됩니다.
  • **데스크톱/모바일 분기 처리 문제**: PC 브라우저와 모바일 OS 브라우저 간의 공유 동작이 달라 예외 에러가 빈번했습니다.

2. 기존에는 어떻게 구현했나

초기에는 카카오톡 공유 버튼 하나만 배치하고, 클릭 시 카카오톡 SDK의 Kakao.Share.sendDefault()를 실행하는 방식이었습니다.

// 기존 시도 (카카오 SDK 의존 방식)
function shareResult() {
  Kakao.Share.sendDefault({
    objectType: 'feed',
    content: { ... }
  });
}

그러나 아이폰 Safari나 안드로이드 크롬 사용자가 "라인"이나 "문자메시지(SMS)"로 전송하고 싶을 때는 방법이 없어 서비스 만족도가 크게 떨어졌습니다.

3. 원인은 무엇이었나

웹 환경에서 모바일 OS(iOS/Android)의 공유 시스템에 접근하는 표준 API인 Web Share API (navigator.share)를 사용하지 않고 특정 3rd party SDK에 의존했기 때문입니다.

4. 실패했던 방법

  • **단순 URL 복사만 제공**: `navigator.clipboard.writeText()`만 적용했더니 사용자가 "복사되었습니다" 팝업을 본 뒤 직접 메신저를 켜고 붙여넣어야 해서 공유 행동 전환율이 대폭 감소.
  • **사용자 제스처 없이 `navigator.share` 호출**: 버튼 클릭 이벤트 핸들러 외부에서 비동기로 호출 시 브라우저 보안 정책(User Activation Required)에 걸려 `NotAllowedError` 발생.

5. 최종 해결 방법

Modern Web Standard API인 Web Share API + Graceful Fallback Strategy를 구축했습니다.

  • **`navigator.share` 호환성 확인**: 브라우저가 Web Share API를 지원하는지(`navigator.share !== undefined`) 체크합니다.
  • **네이티브 공유 시트 호출**: 모바일 환경일 경우 OS 고유의 공유 창을 띄워 사용자가 카카오톡, 라인, 인스타그램, SMS, AirDrop 등 자유롭게 선택하도록 지원합니다.
  • **User Gesture 및 Secure Context 보장**: HTTPS 환경 및 버튼 `click` 이벤트 핸들러 직후 동기적 맥락에서 `navigator.share()`를 실행합니다.

4. Clipboard Fallback (PC/데스크톱 대응): PC 환경처럼 navigator.share를 지원하지 않는 브라우저에서는 클립보드로 공유 URL을 즉시 복사하고 "링크가 복사되었습니다!" 토스트 안내를 띄웁니다.

6. 수정 전후 코드

`app.js` (프런트엔드 크로스 브라우저 공유 로직)

async function handleShareAction(shareTitle, shareText, shareUrl) {
  // 1. 모바일 브라우저 네이티브 공유창 지원 여부 검사 (Web Share API)
  if (navigator.share) {
    try {
      await navigator.share({
        title: shareTitle || "GoodFruit 과일 맛 분석 결과",
        text: shareText || "내 과일의 맛 점수와 판정 근거를 확인해보세요!",
        url: shareUrl || window.location.href,
      });
      // GA4 공유 성공 이벤트 전송
      gtag("event", "share_click", { method: "web_share_api" });
      return;
    } catch (error) {
      // 사용자가 공유 창을 그냥 닫은 경우는 에러가 아니라 AbortError 임
      if (error.name === "AbortError") {
        console.log("사용자가 공유를 취소했습니다.");
        return;
      }
      console.warn("Web Share API 실행 실패, fallback으로 전환합니다:", error);
    }
  }

  // 2. PC / 미지원 브라우저 Fallback: 클립보드 복사
  try {
    if (navigator.clipboard && window.isSecureContext) {
      await navigator.clipboard.writeText(shareUrl || window.location.href);
    } else {
      // 구형 브라우저 fallback
      const textArea = document.createElement("textarea");
      textArea.value = shareUrl || window.location.href;
      document.body.appendChild(textArea);
      textArea.select();
      document.execCommand("copy");
      document.body.removeChild(textArea);
    }
    showToastMessage("분석 결과 링크가 클립보드에 복사되었습니다!");
    gtag("event", "share_click", { method: "clipboard_copy" });
  } catch (err) {
    showToastMessage("링크 복사에 실패했습니다. 주소창을 직접 복사해주세요.");
  }
}

7. 실제 테스트 결과

  • **공유 유무 선택 자유도**: 카카오톡 외에도 SMS, 라인, 인스타그램 스토리 등 공유 매체가 **5개 이상으로 다변화**.
  • **공유 완료율(Share Rate)**: 웹 네이티브 공유창 도입 후 전체 분석 완료자 대비 공유 행동 실행 비율이 **11.2% -> 24.5%로 2배 이상 상승**.
  • **오류 발생률**: `AbortError` 예외 처리 및 HTTPS Secure Context 보장으로 브라우저 스크립트 에러 **0%** 달성.

8. 다른 환경에서 주의할 점

  • `navigator.share`는 **HTTPS 보안 연결(Secure Context)**이 적용된 도메인에서만 동작합니다. (`http://`에서는 작동 안 함)
  • `navigator.share({ files: [...] })`처럼 이미지 파일 자체를 공유할 때는 iOS Safari와 안드로이드 Chrome 간에 mime-type 지원 차이가 있으므로 URL 공유 방식을 기본으로 사용하는 것이 안전합니다.

9. 정리

더 이상 웹사이트 하단에 수많은 SNS 공유 아이콘을 나열할 필요가 없습니다. navigator.share 하나면 모바일 앱 수준의 깔끔한 네이티브 공유 경험을 웹 사용자에게 제공할 수 있습니다.

10. 관련 글

  • [사진 한 장으로 과일 맛을 판정하는 서비스를 만든 이유](file:///Users/uram/dev/goodfruit/posts/01-why-built-goodfruit.md)
  • [회원가입 없이 결과를 다시 볼 수 있게 만든 방법](file:///Users/uram/dev/goodfruit/posts/03-zero-auth-sharing-structure.md)
  • [카카오톡 링크 미리보기용 OG 이미지 만들기](file:///Users/uram/dev/goodfruit/posts/05-dynamic-og-image-kakaotalk-preview.md)

실제 적용 서비스

모바일 브라우저에서 앱처럼 켜지는 GoodFruit의 네이티브 공유 기능을 직접 체험해 보세요!

👉 [GoodFruit 모바일 웹 공유 체험하기](https://fruit.nxnl.app/?utm_source=tistory&utm_medium=content&utm_campaign=goodfruit&utm_content=04_mobile_web_native_share_api)

내부 원문 복사