커스터마이징
ZeroTalk.init() 에 옵션을 전달해 위젯 외관과 동작을 조정합니다.
ZeroTalk.init({
pluginKey: "YOUR_PLUGIN_KEY",
apiBaseUrl: "https://api.talk.zeroworks.ai/api/v1",
wsUrl: "wss://api.talk.zeroworks.ai/ws/sdk",
title: "고객센터",
greeting: {
text: "안녕하세요! 무엇을 도와드릴까요?",
delay: 3000,
},
border: {
window: "#E0E0E0",
},
});
대시보드 설정과 겹칠 때
같은 항목을 대시보드(채팅 설정 → 연동 / 개발 → 연동 설정 → 웹사이트 연동)에서도 설정할 수 있습니다. 둘이 겹치면 init() 에 넘긴 값이 이깁니다.
hideLauncher·hideGreeting·launcherSize·position·launcherIcon·homeTheme·greeting.text·greeting.delay·greeting.onlineText·greeting.offlineText·border를init()에 넘기면, 대시보드에서 그 항목을 아무리 바꿔도 반영되지 않습니다.border는 면(채팅창 · 런처 · 인사 말풍선)마다 따로 판정합니다. 넘긴 면만 대시보드 설정이 무시되고, 넘기지 않은 면은 대시보드 값을 그대로 씁니다.- 그래서 운영팀이 대시보드로 관리하길 원하는 항목은
init()에서 아예 빼두는 편이 좋습니다. - 반대로 노출 시간, 위젯 숨김 페이지, 답변 속도, 말풍선 색상 같은 항목은
init()옵션이 없고 대시보드에서만 설정합니다.
인사 말풍선은 대시보드의 인사 말풍선 표시 가 켜져 있어야 뜨고, 기본값은 꺼짐입니다. 런처가 숨겨져 있거나(디바이스별 숨김·노출 시간 밖) 하면 말풍선도 함께 숨습니다. greeting.text 만 넘겨서는 뜨지 않습니다.
옵션
| 옵션 | 타입 | 기본값 | 설명 |
|---|---|---|---|
pluginKey | string | (필수) | Plugin Key |
title | string | — | 위젯 헤더 타이틀 |
hideLauncher | boolean | (미지정) | 런처 버튼 숨기기. 넘기지 않으면 대시보드 설정(노출 시간 · 디바이스별 숨김 · 위젯 숨김 페이지)을 따릅니다. false 를 명시하면 그 설정이 모두 무시되고 런처가 항상 보입니다 |
hideGreeting | boolean | (미지정) | 인사 말풍선 숨기기. 넘기지 않으면 대시보드의 인사 말풍선 표시 설정을 따릅니다(기본 꺼짐). false 를 명시하면 그 설정이 무시되고 말풍선이 항상 보입니다 |
launcherSize | "small" | "medium" | "large" | number | 위젯 기본값 (73px) | 런처 크기. 지정하지 않으면 대시보드 설정을 따르고, 그것도 없으면 73px |
position | { top, bottom, left, right } | 대시보드 위치 설정 (없으면 우하단 20px) | 위젯 위치 (px). 넘기지 않으면 대시보드의 위치 / 위치 조정 가로·세로(디바이스별)를 따릅니다. 넘기면 세로는 bottom 이 top 보다, 가로는 right 가 left 보다 우선합니다 |
launcherIcon | string | — | 커스텀 런처 아이콘 이미지 URL (PNG · JPG · WebP · SVG 파일 URL 또는 data: URI). <img src> 에 그대로 들어가므로 인라인 <svg> 마크업은 쓸 수 없습니다. 넘기면 대시보드의 버튼 아이콘 설정은 무시됩니다 |
launcherGlyph | "brand" | "message-line" | "message" | "headset" | "brand" | 기본 런처에 그릴 내장 아이콘. 우선순위는 launcherIcon > 대시보드 버튼 아이콘 > launcherGlyph 입니다 — 대시보드에 이미지를 업로드해 둔 워크스페이스에서는 이 옵션이 적용되지 않습니다 |
homeTheme | "full" | "topImage" | "dark" | 대시보드 설정 (없으면 "full") | 홈 화면 배경 형태 (풀커버형 / 상단 이미지형 / 단색 배경형). 넘기지 않으면 대시보드의 홈 화면 테마 설정을 따릅니다 |
autoStart | boolean | true | 자동 연결 |
keepChannel | boolean | false | 채널 이탈 후에도 채널 유지 |
greeting.text | string | — | 인사 메시지 텍스트 |
greeting.delay | number | (미지정) | 인사 말풍선이 뜨기까지의 지연 (ms). 넘기지 않으면 대시보드의 말풍선 표시 지연(0~60000ms)을 따릅니다. 넘기면 그 값이 이깁니다 |
greeting.onlineText | string | — | 온라인 상태 텍스트 |
greeting.offlineText | string | — | 오프라인 상태 텍스트 |
greeting.hideStatus | boolean | false | 인사 말풍선의 온라인/오프라인 상태 표시 숨김 |
greeting.dismissOnClick | boolean | true | 인사 말풍선을 클릭하면 페이지 세션 동안 닫힘 |
border.window | string | { color, width } | — | 채팅 창 테두리 |
border.launcher | string | { color, width } | — | 런처 버튼 테두리 |
border.greeting | string | { color, width } | — | 인사 말풍선 테두리 |
language | "auto" | "ko" | "en" | "zh-CN" | "zh-TW" | "ja" | "auto" | 위젯 UI 언어. "auto" 는 브라우저 언어를 따름 |
theme | Partial<ThemeTokens> | — | 색상·여백·글꼴 등 CSS 변수 토큰 오버라이드. 글꼴은 위젯 글꼴 바꾸기 참고 |
locale | Partial<WidgetLocale> | — | 개별 문구 로컬라이즈 (예: 입력창 placeholder) |
sound | { url, playWhen? } | — | 새 메시지 알림음. playWhen 은 "always" 또는 "whenClosed" (기본 "whenClosed") |
showUnreadBadge | boolean | false | 미읽음 메시지가 있을 때 런처에 빨간 점 표시 |
onUnreadChange | (count: number) => void | — | 미읽음 수 변경 콜백 |
enablePageTracking | boolean | false | SPA 라우트 변경 시 page_view 이벤트 전송. 활성화 시 모든 방문자에 contact 가 생성되므로 KPI · 과금 영향을 검토한 뒤 켜세요 |
memberId | string | — | 로그인 사용자 식별자 — 회원 인증 |
memberHash | string | — | memberId 의 HMAC 서명 — 회원 인증 |
profile | object | — | 이름·이메일 등 회원 프로필 — 회원 인증 |
customFields | object | — | 주문번호 같은 업무 값. 대시보드에 미리 정의한 필드 키만 보낼 수 있습니다 — 회원 인증 |
identityToken | () => string | Promise<string> | — | 서명된 회원 정보(Sealed Identity Token)를 발급하는 콜백. memberId 로 회원이 식별된 요청에 한해 매번 호출되어 profile · customFields 대신 이 토큰이 전송됩니다. 익명 방문자이거나 콜백이 실패·빈 값을 반환하면 서명 없는 profile · customFields 전송으로 되돌아갑니다 — 회원 인증 |
cspNonce | string | — | CSP script-src/style-src 에 nonce 를 쓰는 사이트에서 전달 |
노출 시간, 위젯 숨김 페이지, 다른 문의 방법, 답변 속도, 말풍선 색상, 메시지 글자 크기처럼 init() 옵션이 없는 설정은 대시보드에서만 바꿉니다 — 위젯 커스터마이징(대시보드) 참고.
도메인 제한도 위젯 옵션이 아니라 Plugin Key 별 허용 도메인으로 설정합니다.
테두리 설정
채팅 창, 런처 버튼, 인사 말풍선에 각각 독립적으로 테두리를 적용할 수 있습니다. 색상만 지정하면 두께는 1px이 기본값이며, 두께를 바꾸려면 객체로 전달합니다.
ZeroTalk.init({
pluginKey: "YOUR_PLUGIN_KEY",
apiBaseUrl: "https://api.talk.zeroworks.ai/api/v1",
wsUrl: "wss://api.talk.zeroworks.ai/ws/sdk",
border: {
window: "#E0E0E0", // 1px (기본)
launcher: { color: "#4589FF", width: 2 }, // 2px
greeting: { color: "#E0E0E0", width: 3 }, // 3px
},
});
각 속성은 생략 가능하며, 생략한 면은 대시보드의 테두리 설정을 따릅니다(대시보드에도 설정이 없으면 테두리가 표시되지 않습니다).
init() 으로 지정한 테두리는 항상 실선입니다대시보드에는 실선 / 점선 / 도트 스타일 선택이 있지만, border 옵션에는 스타일 항목이 없어 solid 로만 그려집니다. 점선·도트가 필요하면 대시보드에서 설정하고 border 옵션은 넘기지 마세요 — 이 옵션을 넘기는 순간 그 면의 대시보드 테두리 설정은 무시됩니다.
위젯 글꼴 바꾸기
상담창 안 글자는 위젯 전용 글꼴로 그립니다. 굵은 글자(600·700)는 위젯이 https://cdn.talk.zeroworks.ai 에서 불러오는 Pretendard 로, 보통 굵기 글자는 페이지에 등록됐거나 기기에 설치된 Pretendard 가 있으면 그것으로, 없으면 기기 기본 글꼴로 그립니다. 사이트 CSS 의 글꼴 지정은 * { font-family: ... !important } 처럼 전체에 걸어도 위젯 안 글자에 적용되지 않습니다.
위젯 글꼴은 방문자가 상담창을 처음 열 때 불러옵니다. 상담창을 열지 않은 화면(런처 버튼·인사 말풍선·안 읽은 개수)은 글꼴 파일을 받지 않고, 페이지나 기기에 있는 Pretendard 또는 기기 기본 글꼴로 그립니다. 상담창을 열면 글꼴 선언 파일 하나와 화면에 나온 글자의 글꼴 조각만 받으므로, 상담창을 열지 않는 방문자에게는 위젯 글꼴 요청이 없습니다.
사이트 글꼴로 맞추려면 theme 옵션에 --zerotalk-font-family 를 넘깁니다.
ZeroTalk.init({
pluginKey: "YOUR_PLUGIN_KEY",
apiBaseUrl: "https://api.talk.zeroworks.ai/api/v1",
wsUrl: "wss://api.talk.zeroworks.ai/ws/sdk",
theme: {
"--zerotalk-font-family": "'Noto Sans KR', sans-serif",
},
});
- 넘긴 값이 위젯의 기본 글꼴 목록 전체를 대신합니다. 굵은 글자도 이 글꼴로 그리므로 끝에
sans-serif같은 대체 글꼴을 붙이세요. - 위젯은 지정한 글꼴의 파일을 따로 불러오지 않습니다. 사이트 페이지에서 그 글꼴을 불러와 두세요.
- 지정한 목록에 위젯 글꼴(
'ZeroTalk Pretendard')이 없으면 위젯은 상담창을 열 때도 글꼴 선언 파일을 받지 않습니다. 사이트 글꼴이나 시스템 글꼴로 통일하면서 위젯 글꼴 요청을 없애려면 이 방법을 쓰세요. - 이 변수는 사이트 CSS 가 아니라
theme옵션으로 넘깁니다. 위젯이 시작할 때theme값(넘기지 않았으면 기본값)을 위젯 요소의 인라인 스타일로 써 두기 때문입니다.
style-src·font-src 를 지정한 사이트font-src 에 https://cdn.talk.zeroworks.ai 가 없거나, style-src 가 그 주소도 cspNonce 로 넘긴 nonce 도 허용하지 않으면 굵은 글자용 Pretendard 를 불러오지 못해, 굵은 글자도 보통 굵기 글자처럼 페이지·기기의 Pretendard 나 기기 기본 글꼴로 그립니다. 위젯이 넣는 것은 글꼴 선언 파일(faces.css)을 가리키는 <link rel="stylesheet"> 하나이고, cspNonce 를 넘기면 그 <link> 에 nonce 를 붙입니다.
런처만 먼저 받기
Cafe24 앱으로 설치한 상점은 페이지를 열 때 런처 버튼과 인사 말풍선만 그리는 작은 파일(약 12KB)을 먼저 받고, 상담창 본체(약 190KB)는 방문자가 런처를 처음 클릭할 때 받습니다. 위젯 설정을 정상적으로 받으면 상담창을 열지 않는 방문자에게는 본체 전송이 없고, 대시보드의 런처 설정(색·크기·아이콘·위치·노출 시간·숨김 페이지·인사 말풍선)은 첫 화면부터 그대로 적용됩니다. 설치 스니펫을 직접 붙인 사이트는 지금처럼 본체를 바로 받습니다.
- 첫 클릭 뒤 상담창이 열리기까지 본체를 받는 시간만큼 걸립니다. 그동안 런처는 로딩 상태로 보입니다.
- 클릭 전에 호출한
ZeroTalk.identify()·logout()은 순서대로 본체에 전달됩니다. 본체가 오기 전에destroy()를 부르면 런처를 지우고 쌓인 호출도 버립니다.ZeroTalk.init()의 반환값은 본체가 오기 전에는null입니다.getInstance()는 런처가 화면에 그려진 뒤부터 본체가 올 때까지open()하나만 가진 객체를 돌려주고(그려지기 전에는null),open()은 런처를 누른 것과 같습니다(본체를 받아 엽니다). 그 밖의 메서드는 본체가 온 뒤getInstance()로 다시 얻어 부릅니다. - 런처만 그린 요소의 id 는
zerotalk-facade이고, 본체가 화면에 나타나는 순간 사라집니다. 사이트 CSS 로 변수를 줄 때는 아래 예시처럼#zerotalk-chat-widget, #zerotalk-facade두 선택자에 함께 주세요.#zerotalk-chat-widget하나뿐이면 첫 클릭 전 런처에는 적용되지 않아, 클릭 순간 런처 자리가 바뀝니다. - 안 읽은 개수 표시(
showUnreadBadge)는 본체가 와야 보입니다.
런처가 안 뜰 때
- 위젯 설정을 받지 못하면(한 번 더 시도하고, 시도마다 10초까지 기다린 뒤에도) 런처만 먼저 그리지 않고 상담창 본체를 바로 받습니다. 이때는 런처만 먼저 받는 설치가 아닐 때와 똑같이 동작합니다.
- 대시보드의 노출 시간 밖이거나, 위젯 숨김 페이지에 든 경로이거나, 그 디바이스에서 버튼 숨기기를 켰다면 런처가 보이지 않는 것이 정상입니다. 대시보드 설정을 먼저 확인하세요.
쇼핑몰 하단 바를 피해 런처 올리기
쇼핑몰·랜딩페이지에는 화면 아래에 고정 바(구매하기 버튼, 쿠키 안내, 퀵메뉴)가 있는 경우가 많습니다. 런처가 그 바에 가리거나 너무 붙어 보일 때, 사이트 CSS 한 줄로 런처를 위로 올릴 수 있습니다.
#zerotalk-chat-widget,
#zerotalk-facade {
--zerotalk-launcher-offset-bottom: 64px;
}
- 대시보드의 위치 조정 세로 값에 더해집니다. 대시보드 값을 그대로 두고 이 변수만 얹으면 됩니다.
- 채팅 창 높이도 함께 조정되므로 창 위쪽이 화면 밖으로 밀리지 않습니다.
- 화면 폭 480px 이하에서 채팅 창을 열면 전체 화면으로 전환되며 이 여백은 자동으로 무시됩니다. 그보다 넓은 화면(태블릿 세로 등)에서는 창이 떠 있는 형태라 여백이 그대로 적용됩니다.
스크롤에 따라 나타났다 사라지는 바
바가 보일 때만 런처를 올리려면, 그 바의 상태를 나타내는 선택자에 값을 다르게 주면 됩니다. JavaScript 없이 CSS 만으로 따라갑니다.
#zerotalk-chat-widget,
#zerotalk-facade {
--zerotalk-launcher-offset-bottom: 0px;
}
/* 하단 바가 보이는 동안에만 런처를 올립니다 */
body:has(#bottom-bar.is-visible) #zerotalk-chat-widget,
body:has(#bottom-bar.is-visible) #zerotalk-facade {
--zerotalk-launcher-offset-bottom: 64px;
}
#bottom-bar.is-visible 부분은 실제 사이트의 하단 바 요소와 그 바가 보일 때 붙는 클래스로 바꿔 쓰세요.
바가 클래스 대신 인라인 스타일로만 숨는다면 CSS 로는 상태를 알 수 없으므로, 사이트 쪽에서 클래스를
토글해 주어야 합니다.
위치는 값이 바뀌는 즉시 이동합니다. 사이트 CSS 에 transition 을 걸어도 위젯 내부에는 전달되지
않으므로 부드러운 전환은 적용되지 않습니다.
다른 요소보다 아래에 두기
런처는 기본적으로 가장 위에 그려집니다. 사이트의 모달이나 배너가 런처에 가려진다면 값을 낮추세요. 이 값은 런처만이 아니라 열린 채팅 창과 인사 말풍선까지 함께 내립니다.
#zerotalk-chat-widget,
#zerotalk-facade {
--zerotalk-z-index: 9999;
}
위젯 내부는 shadow DOM 으로 격리되어 있어, 사이트 CSS 로 런처나 채팅 창 내부 요소를 직접 선택할 수
없습니다. 위 변수들과 theme 옵션의 색상·글꼴 토큰이 바깥에서 조정할 수 있는 전부이고, 그 밖의 외형은
대시보드나 init() 옵션으로 설정합니다. 내부 클래스명을 선택자로 쓰는 방법은 지원하지 않으며 업데이트
시 예고 없이 깨집니다.
사용자 정보 연동
로그인된 사용자 정보를 함께 전달할 수 있습니다. memberHash 발급과 주문번호 같은 업무 값(customFields) 전달은 회원 인증 페이지를 참고하세요.
ZeroTalk.init({
pluginKey: "YOUR_PLUGIN_KEY",
apiBaseUrl: "https://api.talk.zeroworks.ai/api/v1",
wsUrl: "wss://api.talk.zeroworks.ai/ws/sdk",
memberId: "user-123",
memberHash: "HMAC_HASH",
profile: {
name: "홍길동",
phone: "010-1234-5678",
email: "hong@example.com",
},
});
profile 의 표준 키는 name · phone · email · avatar_url 입니다. 그 외 키는 저장되지만 상담원 화면에 표시되지 않으므로, 상담원이 봐야 하는 값은 customFields 를 사용하세요.
JavaScript API
위젯 초기화 후 인스턴스 핸들로 위젯을 제어합니다.
- HTML / Vanilla
- React
전역 ZeroTalk.getInstance() 로 초기화된 위젯 핸들을 얻은 뒤 메서드를 호출합니다.
const widget = ZeroTalk.getInstance();
widget?.open();
widget?.close();
widget?.toggle();
// 런처와 인사 말풍선은 다시 띄우지 않고 그 자리에서 감추거나 보일 수 있습니다.
widget?.showLauncher();
widget?.hideLauncher();
widget?.showGreeting();
widget?.hideGreeting();
// 선택자와 처음 일치하는 요소 하나를 위젯 열기/닫기 토글 버튼으로 씁니다.
// 위젯이 열려 있을 때 누르면 닫힙니다. 반환값을 호출하면 연결이 해제되고,
// 일치하는 요소가 없으면 콘솔 경고만 남기고 아무 동작도 하지 않습니다.
const unbind = widget?.bindTrigger("#help-button");
로그인 상태가 바뀔 때는 destroy() 후 다시 init() 하지 말고 전역 API 를 씁니다.
// 로그인 — 익명 방문자 또는 다른 회원에서 이 회원으로 전환
ZeroTalk.identify({
memberId: "user-123",
memberHash: "HMAC_HASH",
profile: { name: "홍길동" },
});
// 로그아웃 — 저장된 방문자 정보를 지우고 익명 상태로 되돌립니다
ZeroTalk.logout();
// 위젯 제거
ZeroTalk.destroy();
destroy() → init() 으로 회원을 바꾸지는 마세요destroy() 후 init() 으로 표시 옵션을 다시 적용하는 것은 문제가 없습니다. 다만 destroy() 는 위젯 인스턴스만 걷어낼 뿐 저장된 방문자 세션(localStorage · zt_vid 쿠키)은 지우지 않습니다. 그래서 이 패턴으로 로그인한 회원을 전환하면 이전 방문자의 상담 내역이 그대로 이어집니다. 회원 전환은 ZeroTalk.identify(), 로그아웃은 ZeroTalk.logout() 을 사용하세요.
@zerotalk/react-sdk 패키지는 아직 npm 레지스트리에 공개 배포되지 않았습니다. 그 전까지는 HTML / Vanilla 탭의 전역 ZeroTalk API 를 사용하세요. 아래 예시는 공개 출시 후의 사용법입니다.
useZeroTalk() 훅은 보다 풍부한 제어 API를 제공합니다.
import { useZeroTalk } from "@zerotalk/react-sdk";
function ChatButton() {
const {
open,
close,
toggle,
showLauncher,
hideLauncher,
showGreeting,
hideGreeting,
isReady,
connectionStatus,
} = useZeroTalk();
return (
<button onClick={toggle} disabled={!isReady}>
채팅
</button>
);
}