오늘 작업에는 클립보드를 이용하는 부분이 있습니다❗
멤버 초대 모달의 '링크 복사하기' 버튼을 클릭하면 URL을 클립보드에 복사하고, 유저 정보 모달의 '이메일 복사하기' 버튼을 클릭하면 유저의 이메일을 복사해요✨
클립보드를 어떻게 구현해야 할까요🤔 라이브러리를 찾아보기 전에 저의 해답지인 MDN을 찾아볼게요!
Clipboard API의 writeText() 메서드를 사용하면 특정 text를 클립보드에 저장하고 Promise를 반환한다고 하네요😀
Clipboard API - writeText 사용법
async function writeClipboardText(text) {
try {
await navigator.clipboard.writeText(text);
} catch (error) {
console.error(error.message);
}
}
링크 복사 - writeText 적용
const handleClick = async () => {
await navigator.clipboard.writeText(`${SERVER_URL}?token=${token}`);
closeModal();
};
<Button className="w-full text-text-inverse" onClick={handleClick}>
링크 복사하기
</Button>;
이메일 복사 - writeText 적용
const handleClick = async () => {
await navigator.clipboard.writeText(member.userEmail);
closeModal();
};
<Button className="w-full text-text-inverse" onClick={handleClick}>
이메일 복사하기
</Button>;
결과 - 클립보드 복사
PC에서 링크와 이메일 모두 잘 복사되네요! 하지만 여기서 끝내면 안 되겠죠.
PC에서 잘 동작하던 기능들이 OS와 브라우저에 따라서 제대로 동작하지 않은 경우를 경험했잖아요🤔
아니나 다를까 노트북과 아이폰 Safari 브라우저로 확인했더니 에러가 발생하네요😭
🚨 문제 상황
MDN의 cilpboard API를 확인해 보니 localhost나 HTTPS 환경에서만 사용할 수 있다고 하네요😥
코드를 통해 직접 확인해 봐야겠죠🤔
const handleClick = async () => {
if (!navigator.clipboard) {
alert('현재 브라우저에서 클립보드 복사를 지원하지 않습니다.');
return;
}
await navigator.clipboard.writeText(member.userEmail);
closeModal();
};
🚩 문제 해결 방법
1️⃣ Document.execCommand() : 지원 중단
2️⃣ react-copy-to-clipboard
2️⃣ react-copy-to-clipboard 라이브러리를 사용하면 라이브러리에서 제공하는 간단한 컴포넌트를 이용해 복사 기능을 구현할 수 있지만, 저희 프로젝트는 React 19 버전이라 사용이 불가능했어요😭
안타깝게도 위 메서드는 지원 중단되어 권장되지 않는다고 하네요😭 하지만 저에게는 방법이 없습니다. 찾아보니 execCommand() 메서드가 아직 많은 브라우저에서 동작하네요.
🌈 문제 해결
execCommand를 이용한 텍스트 복사 함수
const copyWithExecCommand = (text: string) => {
const textArea = document.createElement('textarea');
textArea.value = text;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
};
링크 복사 - writeText 적용
const handleClick = async () => {
if (navigator.clipboard && navigator.clipboard.writeText) {
await navigator.clipboard.writeText(`${SERVER_URL}?token=${token}`);
} else {
copyWithExecCommand(`${SERVER_URL}?token=${token}`);
}
closeModal();
};
이메일 복사 - writeText 적용
const handleClick = async () => {
if (navigator.clipboard && navigator.clipboard.writeText) {
await navigator.clipboard.writeText(member.userEmail);
} else {
copyWithExecCommand(member.userEmail);
}
closeModal();
};
결과 - 클립보드 복사
navigator.clipboard를 호환하는 https에서는 기존과 동일하게 동작합니다.
navigator.clipboard를 호환하지 않는 http에서는 아래 과정을 거치게 됩니다.
- 값을 저장하기 위한 textarea라는 요소를 만들고 value 속성에 복사할 값을 할당
- textarea 요소를 html body에 추가하고 선택
- execCommand 메서드를 사용해 클립보드에 텍스트를 복사
- textarea 요소를 html body에서 삭제
Document.execCommand()가 지원 중단되었다고는 하지만, 덕분에 navigator.clipbaord를 호환하지 않는 http 환경에서도 안전하게 클립보드 복사 기능을 구현할 수 있게 되었어요😊
'프로젝트 > Next+TypeScript' 카테고리의 다른 글
[Coworkers] 할 일 리스트 페이지 작업 (협업) (1) | 2025.02.04 |
---|---|
[Coworkers] Axios interceptor 적용 (token 적용, refresh token을 이용한 토큰 재발급) (0) | 2025.02.03 |
[맛길] API Routes를 이용한 API 구축 (2) | 2025.01.24 |
[Coworkers] 팀 생성 페이지 작업 (feat. 빌드 타임 에러 수정) (1) | 2025.01.23 |
[Coworkers] 팀 생성 페이지 작업 (API 연동) (0) | 2025.01.22 |