react 카카오 공유하기 버튼 만들기
카카오톡 공유하기 버튼을 만들어 보도록 하겠습니다. 생각보다 자주 쓰는 기능입니다.
react 에서 핵심은 kakao api가 로드 된 후 공유버튼을 렌더링하는 것입니다. 카카오 공유버튼이 작동하지 않는 이유 중 하나가 kakao api가 로드 되기 전에 버튼이 렌더링되어 공유하기가 활성화가 안되기 때문입니다.
카카오 sdk 로딩하기 @쉐어버튼이 들어가는 부모 컴포넌트
const [shareButton, setShareButton] = useState(false);
...
useEffect(() => {
const script = document.createElement("script");
script.src = "https://developers.kakao.com/sdk/js/kakao.js";
script.async = true;
document.body.appendChild(script);
// 스크립트가 로드 된 후 쉐어버튼 렌더링
script.onload = () => {
setShareButton(true);
};
return () => {
document.body.removeChild(script);
};
}, []);
// sdk가 로딩된 후 쉐어버튼 렌더링
{shareButton && (
<ShareButton
url={process.env.NEXT_PUBLIC_FRONT + router.asPath}
post={ssrData}
/>
)}
...
ShareButton 컴포넌트
useEffect(() => {
const createKakaoButton = () => {
if (window.Kakao) {
// 카카오 스크립트가 로드된 경우 init
const kakao = window.Kakao;
if (!kakao.isInitialized()) {
kakao.init(process.env.NEXT_PUBLIC_KAKAO_API);
}
kakao.Link.createDefaultButton({
container: "#kakao-link-btn",
objectType: "feed",
content: {
title: post.title,
description: post.content,
// imageUrl 이 없으면 동작 안하기 때문에 default 이미지를 준비해 두기
imageUrl: post.thumbnail
? process.env.NEXT_PUBLIC_SERVER + post.thumbnail
: process.env.NEXT_PUBLIC_FRONT + "/images/tilnote-square.png",
link: {
mobileWebUrl: url,
webUrl: url,
},
},
buttons: [
{
title: "웹으로 보기",
link: {
mobileWebUrl: url,
webUrl: url,
},
},
],
});
}
};
createKakaoButton();
}, [post, url]);
...
// 카카오 공유하기 버튼. id kakao-link-btn 부분에 kakao 공유하기가 설정됨
<div style={{ marginLeft: "1rem" }}>
<img
id="kakao-link-btn"
src="/images/kakao-share.png"
style={style}
alt="카카오로 공유하기"
/>
</div>
이렇게 하니 잘 작동한다.
자주 생기는 에러
because the scheme does not have a registered handler. : 크롬에서 모바일 등으로 유저 에이전트를 변경했을 때. 모바일과 PC가 동작이 달라서 pc 크롬에서 모바일로 유저 에이전트로 변경하면 작동이 안된다고 한다.
because a user gesture is required. : sdk 가 로딩되지 않거나 나중에 로딩됐을 때 발생.
업그레이드
sdk가 로딩 된 후 버튼이 나타나게 되면 성능에서 Time to interactive가 느리게 표현되는 문제가 있었다.
그래서 shareButton으로 조건식을 다는 블록킹 요소를 없애고 화면을 먼저 보여준 후 클릭 할 때 버튼을 만들어서 세팅하고 눌러주는 방식으로 개선했다.
기존 sync를 주는 javascript를 없애고 next의 body 앞부분에 다음과 같이 next의 Script를 이용하여 로딩.
<Script src="https://developers.kakao.com/sdk/js/kakao.js" />
조건식을 없앰.
// {shareButton && (
<ShareButton
url={process.env.NEXT_PUBLIC_FRONT + router.asPath}
post={ssrData}
/>
// )}
<Image
src="/images/kakao-share.png"
width={40}
height={40}
style={style}
id="kakao-link-btn"
alt="카카오로 공유하기"
onClick={() => createKakaoButton(post, markdownContent, url)}
/>
@createKakaoButton
클릭 시 동적으로 버튼 생성 후 눌러주기
const createKakaoButton = (post, content, url) => {
...기존과 동일
const kakaoBtn = document.querySelector("#kakao-link-btn");
kakaoBtn.click();
kakao.Link.cleanup();
// 버튼을 만들어 주고 클릭 후 초기화 시킨다.
}
공유하기
조회수 : 2428