├── .eslintrc.js ├── .gitignore ├── LICENSE ├── README.md ├── dist ├── tawk-messenger-react.es.js └── tawk-messenger-react.umd.js ├── docs ├── api-reference.md └── how-to-use.md ├── images └── tawk-react-logo.png ├── package.json ├── src ├── __tests__ │ ├── Install.spec.js │ └── TawkMessenger.spec.js ├── index.js └── utils │ ├── helper.js │ └── widget.js ├── vite.config.js └── yarn.lock /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root : true, 3 | env : { 4 | node : true, 5 | jest : true, 6 | es2020 : true 7 | }, 8 | extends : [ 9 | 'plugin:react/recommended', 10 | 'plugin:react/jsx-runtime', 11 | 'eslint:recommended' 12 | ], 13 | ignorePatterns : ['/dist/**'], 14 | rules : { 15 | 'no-console' : ['error', { allow : ['warn', 'error'] }], 16 | 'no-debugger' : 'error', 17 | 'no-var' : 'off', 18 | semi : ['error', 'always'], 19 | indent : [1, 'tab'], 20 | 'space-before-function-paren' : [ 21 | 'warn', 22 | { 23 | anonymous : 'always', 24 | named : 'never' 25 | } 26 | ], 27 | 'key-spacing' : [ 28 | 'warn', 29 | { 30 | beforeColon : true 31 | } 32 | ], 33 | 'operator-linebreak' : ['error', 'after'], 34 | 'no-nested-ternary' : 'error', 35 | quotes : ['error', 'single'], 36 | 'arrow-parens' : ['error', 'always'], 37 | 'react/jsx-uses-react' : 'off', 38 | 'react/react-in-jsx-scope' : 'off', 39 | 'no-redeclare' : 'off' 40 | }, 41 | settings : { 42 | react : { 43 | version : 'detect' 44 | } 45 | }, 46 | parser : 'babel-eslint' 47 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | 84 | # Gatsby files 85 | .cache/ 86 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 87 | # https://nextjs.org/blog/next-9-1#public-directory-support 88 | # public 89 | 90 | # vuepress build output 91 | .vuepress/dist 92 | 93 | # Serverless directories 94 | .serverless/ 95 | 96 | # FuseBox cache 97 | .fusebox/ 98 | 99 | # DynamoDB Local files 100 | .dynamodb/ 101 | 102 | # TernJS port file 103 | .tern-port 104 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 105 | 106 | # dependencies 107 | /node_modules 108 | /.pnp 109 | .pnp.js 110 | 111 | # testing 112 | /coverage 113 | 114 | # production 115 | /build 116 | 117 | # misc 118 | .DS_Store 119 | .env.local 120 | .env.development.local 121 | .env.test.local 122 | .env.production.local 123 | 124 | npm-debug.log* 125 | yarn-debug.log* 126 | yarn-error.log* 127 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2022 tawk.to inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Tawk React logo 5 |

6 | 7 |
8 | 9 | ## Features 10 | * Using React Hooks 11 | * Documented and self-explaining methods 12 | * Small size without any external libraries 13 | * All Javascript API methods are available 14 | * Maintained by the [tawk.to](https://www.tawk.to/) team. 15 | 16 |
17 | 18 | ## Installation 19 | The plugins are available from the node and yarn package managers. 20 | ```bash 21 | # Node 22 | npm install @tawk.to/tawk-messenger-react 23 | 24 | # Yarn 25 | yarn add @tawk.to/tawk-messenger-react 26 | ``` 27 | 28 |
29 | 30 | ## Quickstart 31 | Import **tawk-messenger-react** into the App.js file of your **src/** folder. The **propertyId** and **widgetId** will 32 | be found on your tawk Dashboard. 33 | 34 | Log in to your account and go to **Administration > Channels > Chat Widget**. 35 | 36 | When using the API, you will need to use the **useRef** to access the object functions from the **tawk-messenger-react** component. 37 | 38 | ```js 39 | import TawkMessengerReact from '@tawk.to/tawk-messenger-react'; 40 | 41 | function App() { 42 | return ( 43 |
44 | 47 |
48 | ); 49 | } 50 | ``` 51 | 52 |
53 | 54 | ## Documentation 55 | This project includes a `docs` folder with more details on the following: 56 | 1. [How to Use](docs/how-to-use.md) 57 | 1. [API Reference](docs/api-reference.md) 58 | 59 |
60 | 61 | ## Other JS frameworks we support 62 | - [Vue Js](https://github.com/tawk/tawk-messenger-vue) 63 | - [Angular Js](https://github.com/tawk/tawk-messenger-angular) 64 | - [Ember Js](https://github.com/tawk/tawk-messenger-ember) 65 | 66 |
67 | 68 | ## Frequently Asked Questions 69 | 70 | **Do you have a knowledge base or article to support implementation?** 71 | 72 | Here is our guide for the [React.js integration](https://help.tawk.to/article/react-js ) 73 | 74 | **Where can I find more information and support?** 75 | 76 | Visit our [help center](https://help.tawk.to) or reach out in the chat on our [website](https://tawk.to). Our agents are available to assist you 24/7. 77 | 78 | **Where can I submit a suggestion or report a bug?** 79 | 80 | Check to see if the issue already exists. If not, open a new issue in the [Issues tab](https://github.com/tawk/tawk-messenger-vue/issues) -------------------------------------------------------------------------------- /dist/tawk-messenger-react.es.js: -------------------------------------------------------------------------------- 1 | import { forwardRef, useEffect, useImperativeHandle } from "react"; 2 | var propTypes = { exports: {} }; 3 | var ReactPropTypesSecret$1 = "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"; 4 | var ReactPropTypesSecret_1 = ReactPropTypesSecret$1; 5 | var ReactPropTypesSecret = ReactPropTypesSecret_1; 6 | function emptyFunction() { 7 | } 8 | function emptyFunctionWithReset() { 9 | } 10 | emptyFunctionWithReset.resetWarningCache = emptyFunction; 11 | var factoryWithThrowingShims = function() { 12 | function shim(props, propName, componentName, location, propFullName, secret) { 13 | if (secret === ReactPropTypesSecret) { 14 | return; 15 | } 16 | var err = new Error( 17 | "Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types" 18 | ); 19 | err.name = "Invariant Violation"; 20 | throw err; 21 | } 22 | shim.isRequired = shim; 23 | function getShim() { 24 | return shim; 25 | } 26 | var ReactPropTypes = { 27 | array: shim, 28 | bigint: shim, 29 | bool: shim, 30 | func: shim, 31 | number: shim, 32 | object: shim, 33 | string: shim, 34 | symbol: shim, 35 | any: shim, 36 | arrayOf: getShim, 37 | element: shim, 38 | elementType: shim, 39 | instanceOf: getShim, 40 | node: shim, 41 | objectOf: getShim, 42 | oneOf: getShim, 43 | oneOfType: getShim, 44 | shape: getShim, 45 | exact: getShim, 46 | checkPropTypes: emptyFunctionWithReset, 47 | resetWarningCache: emptyFunction 48 | }; 49 | ReactPropTypes.PropTypes = ReactPropTypes; 50 | return ReactPropTypes; 51 | }; 52 | { 53 | propTypes.exports = factoryWithThrowingShims(); 54 | } 55 | var PropTypes = propTypes.exports; 56 | const isValidString = (value) => { 57 | if (!value || value.length === 0) { 58 | return false; 59 | } 60 | return value !== null && value !== void 0 && typeof value === "string"; 61 | }; 62 | const loadScript = ({ propertyId = "", widgetId = "", embedId = "", basePath = "tawk.to" }) => { 63 | if (embedId.length) { 64 | if (!document.getElementById(embedId)) { 65 | const element = document.createElement("div"); 66 | element.id = embedId; 67 | document.body.appendChild(element); 68 | } 69 | window.Tawk_API.embedded = embedId; 70 | } 71 | const script = document.createElement("script"); 72 | script.async = true; 73 | script.src = `https://embed.${basePath}/${propertyId}/${widgetId}`; 74 | script.charset = "UTF-8"; 75 | script.setAttribute("crossorigin", "*"); 76 | const firstScript = document.getElementsByTagName("script")[0]; 77 | firstScript.parentNode.insertBefore(script, firstScript); 78 | }; 79 | const TawkMessenger = forwardRef((props, ref) => { 80 | useEffect(() => { 81 | load(); 82 | }, []); 83 | const load = () => { 84 | if (!isValidString(props.propertyId)) { 85 | console.error("[Tawk-messenger-react warn]: You didn't specified 'propertyId' property in the plugin."); 86 | return; 87 | } 88 | if (!isValidString(props.widgetId)) { 89 | console.error("[Tawk-messenger-react warn]: You didn't specified 'widgetId' property in the plugin."); 90 | return; 91 | } 92 | if (!window || !document) { 93 | return; 94 | } 95 | init(); 96 | }; 97 | const init = () => { 98 | window.Tawk_API = window.Tawk_API || {}; 99 | window.Tawk_LoadStart = new Date(); 100 | loadScript({ 101 | propertyId: props.propertyId, 102 | widgetId: props.widgetId, 103 | embedId: props.embedId, 104 | basePath: props.basePath 105 | }); 106 | if (props.customStyle && typeof props.customStyle === "object") { 107 | window.Tawk_API.customStyle = props.customStyle; 108 | } 109 | mapCallbacks(); 110 | }; 111 | useImperativeHandle(ref, () => ({ 112 | maximize: () => { 113 | return window.Tawk_API.maximize(); 114 | }, 115 | minimize: () => { 116 | return window.Tawk_API.minimize(); 117 | }, 118 | toggle: () => { 119 | return window.Tawk_API.toggle(); 120 | }, 121 | popup: () => { 122 | return window.Tawk_API.popup(); 123 | }, 124 | showWidget: () => { 125 | return window.Tawk_API.showWidget(); 126 | }, 127 | hideWidget: () => { 128 | return window.Tawk_API.hideWidget(); 129 | }, 130 | toggleVisibility: () => { 131 | return window.Tawk_API.toggleVisibility(); 132 | }, 133 | endChat: () => { 134 | return window.Tawk_API.endChat(); 135 | }, 136 | getWindowType: () => { 137 | return window.Tawk_API.getWindowType(); 138 | }, 139 | getStatus: () => { 140 | return window.Tawk_API.getStatus(); 141 | }, 142 | isChatMaximized: () => { 143 | return window.Tawk_API.isChatMaximized(); 144 | }, 145 | isChatMinimized: () => { 146 | return window.Tawk_API.isChatMinimized(); 147 | }, 148 | isChatHidden: () => { 149 | return window.Tawk_API.isChatHidden(); 150 | }, 151 | isChatOngoing: () => { 152 | return window.Tawk_API.isChatOngoing(); 153 | }, 154 | isVisitorEngaged: () => { 155 | return window.Tawk_API.isVisitorEngaged(); 156 | }, 157 | onLoaded: () => { 158 | return window.Tawk_API.onLoaded; 159 | }, 160 | onBeforeLoaded: () => { 161 | return window.Tawk_API.onBeforeLoaded; 162 | }, 163 | widgetPosition: () => { 164 | return window.Tawk_API.widgetPosition(); 165 | }, 166 | visitor: (data2) => { 167 | window.Tawk_API.visitor = data2; 168 | }, 169 | setAttributes: (attribute, callback) => { 170 | window.Tawk_API.setAttributes(attribute, callback); 171 | }, 172 | addEvent: (event, metadata, callback) => { 173 | window.Tawk_API.addEvent(event, metadata, callback); 174 | }, 175 | addTags: (tags, callback) => { 176 | window.Tawk_API.addTags(tags, callback); 177 | }, 178 | removeTags: (tags, callback) => { 179 | window.Tawk_API.removeTags(tags, callback); 180 | }, 181 | switchWidget: (options, callback) => { 182 | window.Tawk_API.switchWidget(data, callback); 183 | } 184 | })); 185 | const mapCallbacks = () => { 186 | window.addEventListener("tawkLoad", () => { 187 | props.onLoad(); 188 | }); 189 | window.addEventListener("tawkStatusChange", (status) => { 190 | props.onStatusChange(status.detail); 191 | }); 192 | window.addEventListener("tawkBeforeLoad", () => { 193 | props.onBeforeLoad(); 194 | }); 195 | window.addEventListener("tawkChatMaximized", () => { 196 | props.onChatMaximized(); 197 | }); 198 | window.addEventListener("tawkChatMinimized", () => { 199 | props.onChatMinimized(); 200 | }); 201 | window.addEventListener("tawkChatHidden", () => { 202 | props.onChatHidden(); 203 | }); 204 | window.addEventListener("tawkChatStarted", () => { 205 | props.onChatStarted(); 206 | }); 207 | window.addEventListener("tawkChatEnded", () => { 208 | props.onChatEnded(); 209 | }); 210 | window.addEventListener("tawkPrechatSubmit", (data2) => { 211 | props.onPrechatSubmit(data2.detail); 212 | }); 213 | window.addEventListener("tawkOfflineSubmit", (data2) => { 214 | props.onOfflineSubmit(data2.detail); 215 | }); 216 | window.addEventListener("tawkChatMessageVisitor", (message) => { 217 | props.onChatMessageVisitor(message.detail); 218 | }); 219 | window.addEventListener("tawkChatMessageAgent", (message) => { 220 | props.onChatMessageAgent(message.detail); 221 | }); 222 | window.addEventListener("tawkChatMessageSystem", (message) => { 223 | props.onChatMessageSystem(message.detail); 224 | }); 225 | window.addEventListener("tawkAgentJoinChat", (data2) => { 226 | props.onAgentJoinChat(data2.detail); 227 | }); 228 | window.addEventListener("tawkAgentLeaveChat", (data2) => { 229 | props.onAgentLeaveChat(data2.detail); 230 | }); 231 | window.addEventListener("tawkChatSatisfaction", (satisfaction) => { 232 | props.onChatSatisfaction(satisfaction.detail); 233 | }); 234 | window.addEventListener("tawkVisitorNameChanged", (visitorName) => { 235 | props.onVisitorNameChanged(visitorName.detail); 236 | }); 237 | window.addEventListener("tawkFileUpload", (link) => { 238 | props.onFileUpload(link.detail); 239 | }); 240 | window.addEventListener("tawkTagsUpdated", (data2) => { 241 | props.onTagsUpdated(data2.detail); 242 | }); 243 | window.addEventListener("tawkUnreadCountChanged", (data2) => { 244 | props.onUnreadCountChanged(data2.detail); 245 | }); 246 | }; 247 | return null; 248 | }); 249 | TawkMessenger.displayName = "TawkMessenger"; 250 | TawkMessenger.defaultProps = { 251 | customStyle: null, 252 | embedId: "", 253 | basePath: "tawk.to", 254 | onLoad: () => { 255 | }, 256 | onStatusChange: () => { 257 | }, 258 | onBeforeLoad: () => { 259 | }, 260 | onChatMaximized: () => { 261 | }, 262 | onChatMinimized: () => { 263 | }, 264 | onChatHidden: () => { 265 | }, 266 | onChatStarted: () => { 267 | }, 268 | onChatEnded: () => { 269 | }, 270 | onPrechatSubmit: () => { 271 | }, 272 | onOfflineSubmit: () => { 273 | }, 274 | onChatMessageVisitor: () => { 275 | }, 276 | onChatMessageAgent: () => { 277 | }, 278 | onChatMessageSystem: () => { 279 | }, 280 | onAgentJoinChat: () => { 281 | }, 282 | onAgentLeaveChat: () => { 283 | }, 284 | onChatSatisfaction: () => { 285 | }, 286 | onVisitorNameChanged: () => { 287 | }, 288 | onFileUpload: () => { 289 | }, 290 | onTagsUpdated: () => { 291 | }, 292 | onUnreadCountChanged: () => { 293 | } 294 | }; 295 | TawkMessenger.propTypes = { 296 | propertyId: PropTypes.string.isRequired, 297 | widgetId: PropTypes.string.isRequired, 298 | customStyle: PropTypes.object, 299 | embedId: PropTypes.string, 300 | basePath: PropTypes.string, 301 | onLoad: PropTypes.func, 302 | onStatusChange: PropTypes.func, 303 | onBeforeLoad: PropTypes.func, 304 | onChatMaximized: PropTypes.func, 305 | onChatMinimized: PropTypes.func, 306 | onChatHidden: PropTypes.func, 307 | onChatStarted: PropTypes.func, 308 | onChatEnded: PropTypes.func, 309 | onPrechatSubmit: PropTypes.func, 310 | onOfflineSubmit: PropTypes.func, 311 | onChatMessageVisitor: PropTypes.func, 312 | onChatMessageAgent: PropTypes.func, 313 | onChatMessageSystem: PropTypes.func, 314 | onAgentJoinChat: PropTypes.func, 315 | onAgentLeaveChat: PropTypes.func, 316 | onChatSatisfaction: PropTypes.func, 317 | onVisitorNameChanged: PropTypes.func, 318 | onFileUpload: PropTypes.func, 319 | onTagsUpdated: PropTypes.func, 320 | onUnreadCountChanged: PropTypes.func 321 | }; 322 | export { TawkMessenger as default }; 323 | -------------------------------------------------------------------------------- /dist/tawk-messenger-react.umd.js: -------------------------------------------------------------------------------- 1 | (function(o,w){typeof exports=="object"&&typeof module!="undefined"?module.exports=w(require("react")):typeof define=="function"&&define.amd?define(["react"],w):(o=typeof globalThis!="undefined"?globalThis:o||self,o["tawk-messenger-react"]=w(o.React))})(this,function(o){"use strict";var w={exports:{}},C="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED",l=C,T=l;function c(){}function h(){}h.resetWarningCache=c;var k=function(){function e(u,r,t,a,m,p){if(p!==T){var f=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw f.name="Invariant Violation",f}}e.isRequired=e;function i(){return e}var d={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:i,element:e,elementType:e,instanceOf:i,node:e,objectOf:i,oneOf:i,oneOfType:i,shape:i,exact:i,checkPropTypes:h,resetWarningCache:c};return d.PropTypes=d,d};w.exports=k();var n=w.exports;const g=e=>!e||e.length===0?!1:e!=null&&typeof e=="string",y=({propertyId:e="",widgetId:i="",embedId:d="",basePath:u="tawk.to"})=>{if(d.length){if(!document.getElementById(d)){const a=document.createElement("div");a.id=d,document.body.appendChild(a)}window.Tawk_API.embedded=d}const r=document.createElement("script");r.async=!0,r.src=`https://embed.${u}/${e}/${i}`,r.charset="UTF-8",r.setAttribute("crossorigin","*");const t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(r,t)},s=o.forwardRef((e,i)=>{o.useEffect(()=>{d()},[]);const d=()=>{if(!g(e.propertyId)){console.error("[Tawk-messenger-react warn]: You didn't specified 'propertyId' property in the plugin.");return}if(!g(e.widgetId)){console.error("[Tawk-messenger-react warn]: You didn't specified 'widgetId' property in the plugin.");return}!window||!document||u()},u=()=>{window.Tawk_API=window.Tawk_API||{},window.Tawk_LoadStart=new Date,y({propertyId:e.propertyId,widgetId:e.widgetId,embedId:e.embedId,basePath:e.basePath}),e.customStyle&&typeof e.customStyle=="object"&&(window.Tawk_API.customStyle=e.customStyle),r()};o.useImperativeHandle(i,()=>({maximize:()=>window.Tawk_API.maximize(),minimize:()=>window.Tawk_API.minimize(),toggle:()=>window.Tawk_API.toggle(),popup:()=>window.Tawk_API.popup(),showWidget:()=>window.Tawk_API.showWidget(),hideWidget:()=>window.Tawk_API.hideWidget(),toggleVisibility:()=>window.Tawk_API.toggleVisibility(),endChat:()=>window.Tawk_API.endChat(),getWindowType:()=>window.Tawk_API.getWindowType(),getStatus:()=>window.Tawk_API.getStatus(),isChatMaximized:()=>window.Tawk_API.isChatMaximized(),isChatMinimized:()=>window.Tawk_API.isChatMinimized(),isChatHidden:()=>window.Tawk_API.isChatHidden(),isChatOngoing:()=>window.Tawk_API.isChatOngoing(),isVisitorEngaged:()=>window.Tawk_API.isVisitorEngaged(),onLoaded:()=>window.Tawk_API.onLoaded,onBeforeLoaded:()=>window.Tawk_API.onBeforeLoaded,widgetPosition:()=>window.Tawk_API.widgetPosition(),visitor:t=>{window.Tawk_API.visitor=t},setAttributes:(t,a)=>{window.Tawk_API.setAttributes(t,a)},addEvent:(t,a,m)=>{window.Tawk_API.addEvent(t,a,m)},addTags:(t,a)=>{window.Tawk_API.addTags(t,a)},removeTags:(t,a)=>{window.Tawk_API.removeTags(t,a)},switchWidget:(t,a)=>{window.Tawk_API.switchWidget(data,a)}}));const r=()=>{window.addEventListener("tawkLoad",()=>{e.onLoad()}),window.addEventListener("tawkStatusChange",t=>{e.onStatusChange(t.detail)}),window.addEventListener("tawkBeforeLoad",()=>{e.onBeforeLoad()}),window.addEventListener("tawkChatMaximized",()=>{e.onChatMaximized()}),window.addEventListener("tawkChatMinimized",()=>{e.onChatMinimized()}),window.addEventListener("tawkChatHidden",()=>{e.onChatHidden()}),window.addEventListener("tawkChatStarted",()=>{e.onChatStarted()}),window.addEventListener("tawkChatEnded",()=>{e.onChatEnded()}),window.addEventListener("tawkPrechatSubmit",t=>{e.onPrechatSubmit(t.detail)}),window.addEventListener("tawkOfflineSubmit",t=>{e.onOfflineSubmit(t.detail)}),window.addEventListener("tawkChatMessageVisitor",t=>{e.onChatMessageVisitor(t.detail)}),window.addEventListener("tawkChatMessageAgent",t=>{e.onChatMessageAgent(t.detail)}),window.addEventListener("tawkChatMessageSystem",t=>{e.onChatMessageSystem(t.detail)}),window.addEventListener("tawkAgentJoinChat",t=>{e.onAgentJoinChat(t.detail)}),window.addEventListener("tawkAgentLeaveChat",t=>{e.onAgentLeaveChat(t.detail)}),window.addEventListener("tawkChatSatisfaction",t=>{e.onChatSatisfaction(t.detail)}),window.addEventListener("tawkVisitorNameChanged",t=>{e.onVisitorNameChanged(t.detail)}),window.addEventListener("tawkFileUpload",t=>{e.onFileUpload(t.detail)}),window.addEventListener("tawkTagsUpdated",t=>{e.onTagsUpdated(t.detail)}),window.addEventListener("tawkUnreadCountChanged",t=>{e.onUnreadCountChanged(t.detail)})};return null});return s.displayName="TawkMessenger",s.defaultProps={customStyle:null,embedId:"",basePath:"tawk.to",onLoad:()=>{},onStatusChange:()=>{},onBeforeLoad:()=>{},onChatMaximized:()=>{},onChatMinimized:()=>{},onChatHidden:()=>{},onChatStarted:()=>{},onChatEnded:()=>{},onPrechatSubmit:()=>{},onOfflineSubmit:()=>{},onChatMessageVisitor:()=>{},onChatMessageAgent:()=>{},onChatMessageSystem:()=>{},onAgentJoinChat:()=>{},onAgentLeaveChat:()=>{},onChatSatisfaction:()=>{},onVisitorNameChanged:()=>{},onFileUpload:()=>{},onTagsUpdated:()=>{},onUnreadCountChanged:()=>{}},s.propTypes={propertyId:n.string.isRequired,widgetId:n.string.isRequired,customStyle:n.object,embedId:n.string,basePath:n.string,onLoad:n.func,onStatusChange:n.func,onBeforeLoad:n.func,onChatMaximized:n.func,onChatMinimized:n.func,onChatHidden:n.func,onChatStarted:n.func,onChatEnded:n.func,onPrechatSubmit:n.func,onOfflineSubmit:n.func,onChatMessageVisitor:n.func,onChatMessageAgent:n.func,onChatMessageSystem:n.func,onAgentJoinChat:n.func,onAgentLeaveChat:n.func,onChatSatisfaction:n.func,onVisitorNameChanged:n.func,onFileUpload:n.func,onTagsUpdated:n.func,onUnreadCountChanged:n.func},s}); 2 | -------------------------------------------------------------------------------- /docs/api-reference.md: -------------------------------------------------------------------------------- 1 | # API Reference 2 | Welcome to the [tawk.to](https://www.tawk.to) JavaScript API documentation. 3 | 4 | The API provides a flexible set of methods that can be used in your web projects. To invoke one of 5 | the methods below, please be sure to call a method after the embed code on your page. 6 | 7 | Use the JavaScript API to manipulate the chat widget displayed on your website. 8 | 9 |
10 | 11 | ## Table of contents 12 | - [API Reference](#api-reference) 13 | - [Table of contents](#table-of-contents) 14 | - [onLoad](#onload) 15 | - [onStatusChange](#onstatuschange) 16 | - [onBeforeLoad](#onbeforeload) 17 | - [onChatMaximized](#onchatmaximized) 18 | - [onChatMinimized](#onchatminimized) 19 | - [onChatHidden](#onchathidden) 20 | - [onChatStarted](#onchatstarted) 21 | - [onChatEnded](#onchatended) 22 | - [onPrechatSubmit](#onprechatsubmit) 23 | - [onOfflineSubmit](#onofflinesubmit) 24 | - [onChatMessageVisitor](#onchatmessagevisitor) 25 | - [onChatMessageAgent](#onchatmessageagent) 26 | - [onChatMessageSystem](#onchatmessagesystem) 27 | - [onAgentJoinChat](#onagentjoinchat) 28 | - [onAgentLeaveChat](#onagentleavechat) 29 | - [onChatSatisfaction](#onchatsatisfaction) 30 | - [onVisitorNameChanged](#onvisitornamechanged) 31 | - [onFileUpload](#onfileupload) 32 | - [onTagsUpdated](#ontagsupdated) 33 | - [onUnreadCountChanged](#onunreadcountchanged) 34 | - [onLoaded](#onloaded) 35 | - [onBeforeLoaded](#onbeforeloaded) 36 | - [widgetPosition](#widgetposition) 37 | - [visitor](#visitor) 38 | - [autoStart](#autostart) 39 | - [start](#start) 40 | - [shutdown](#shutdown) 41 | - [maximize](#maximize) 42 | - [minimize](#minimize) 43 | - [toggle](#toggle) 44 | - [popup](#popup) 45 | - [getWindowType](#getwindowtype) 46 | - [showWidget](#showwidget) 47 | - [hideWidget](#hidewidget) 48 | - [toggleVisibility](#togglevisibility) 49 | - [getStatus](#getstatus) 50 | - [isChatMaximized](#ischatmaximized) 51 | - [isChatMinimized](#ischatminimized) 52 | - [isChatHidden](#ischathidden) 53 | - [isChatOngoing](#ischatongoing) 54 | - [isVisitorEngaged](#isvisitorengaged) 55 | - [endChat](#endchat) 56 | - [setAttributes](#setattributes) 57 | - [addEvent](#addevent) 58 | - [addTags](#addtags) 59 | - [removeTags](#removetags) 60 | - [secureMode](#securemode) 61 | - [switchWidget](#switchwidget) 62 | - [customstyle](#customstyle) 63 | - [zIndex](#zindex) 64 | - [Visibility](#visibility) 65 | 66 |
67 | 68 | ## onLoad 69 | Callback function invoked right after the widget is rendered. This callback is not supported in 70 | pop out chat window. 71 | 72 | ```js 73 | function App() { 74 | const onLoad = () => { 75 | // place your code here 76 | } 77 | 78 | return ( 79 |
80 | 82 |
83 | ); 84 | } 85 | ``` 86 | 87 |
88 | 89 | ## onStatusChange 90 | Callback function invoked when the page status changes. The function will receive the changed 91 | status which will be either online, away or offline. This callback is not supported in pop out 92 | chat window. 93 | 94 | ```js 95 | function App() { 96 | const onStatusChange = (status) => { 97 | // place your code here 98 | } 99 | 100 | return ( 101 |
102 | 104 |
105 | ); 106 | } 107 | ``` 108 | 109 |
110 | 111 | ## onBeforeLoad 112 | Callback function invoked right when Tawk_API is ready to be used and before the widget is rendered. 113 | This callback is not supported in pop out chat window. 114 | 115 | ```js 116 | function App() { 117 | const onBeforeLoad = () => { 118 | // place your code here 119 | } 120 | 121 | return ( 122 |
123 | 125 |
126 | ); 127 | } 128 | ``` 129 | 130 |
131 | 132 | ## onChatMaximized 133 | Callback function invoked when the widget is maximized. This callback is not supported in pop out 134 | chat window. 135 | 136 | ```js 137 | function App() { 138 | const onChatMaximized = () => { 139 | // place your code here 140 | } 141 | 142 | return ( 143 |
144 | 146 |
147 | ); 148 | } 149 | ``` 150 | 151 |
152 | 153 | ## onChatMinimized 154 | Callback function invoked when the widget is minimized. This callback is not supported in pop out 155 | chat window. 156 | 157 | ```js 158 | function App() { 159 | const onChatMinimized = () => { 160 | // place your code here 161 | } 162 | 163 | return ( 164 |
165 | 167 |
168 | ); 169 | } 170 | ``` 171 | 172 |
173 | 174 | ## onChatHidden 175 | Callback function invoked when the widget is hidden. This callback is not supported in pop out chat 176 | window. 177 | 178 | ```js 179 | function App() { 180 | const onChatHidden = () => { 181 | // place your code here 182 | } 183 | 184 | return ( 185 |
186 | 188 |
189 | ); 190 | } 191 | ``` 192 | 193 |
194 | 195 | ## onChatStarted 196 | Callback function invoked when the widget is started. 197 | 198 | ```js 199 | function App() { 200 | const onChatStarted = () => { 201 | // place your code here 202 | } 203 | 204 | return ( 205 |
206 | 208 |
209 | ); 210 | } 211 | ``` 212 | 213 |
214 | 215 | ## onChatEnded 216 | Callback function invoked when the widget is ended. This callback is not supported in pop out chat 217 | window. 218 | 219 | ```js 220 | function App() { 221 | const onChatEnded = () => { 222 | // place your code here 223 | } 224 | 225 | return ( 226 |
227 | 229 |
230 | ); 231 | } 232 | ``` 233 | 234 |
235 | 236 | ## onPrechatSubmit 237 | Callback function invoked when the Pre-Chat Form is submitted. The submitted form data is passed to 238 | the function. This callback is not supported in pop out chat window. 239 | 240 | ```js 241 | function App() { 242 | const onPrechatSubmit = (data) => { 243 | // place your code here 244 | } 245 | 246 | return ( 247 |
248 | 250 |
251 | ); 252 | } 253 | ``` 254 | 255 |
256 | 257 | ## onOfflineSubmit 258 | Callback function invoked when the Offline form is submitted. The submitted form data is passed to 259 | the function. Form data will contain {name : ”, email : ”, message : ”, questions : []}. This 260 | callback is not supported in pop out chat window. 261 | 262 | ```js 263 | function App() { 264 | const onOfflineSubmit = (data) => { 265 | // place your code here 266 | } 267 | 268 | return ( 269 |
270 | 272 |
273 | ); 274 | } 275 | ``` 276 | 277 |
278 | 279 | ## onChatMessageVisitor 280 | Callback function invoked when message is sent by the visitor. The message is passed to the 281 | function. This callback is not supported in pop out chat window. 282 | 283 | ```js 284 | function App() { 285 | const onChatMessageVisitor = (message) => { 286 | // place your code here 287 | } 288 | 289 | return ( 290 |
291 | 293 |
294 | ); 295 | } 296 | ``` 297 | 298 |
299 | 300 | ## onChatMessageAgent 301 | Callback function invoked when message is sent by the agent. The message is passed to the function. 302 | This callback is not supported in pop out chat window. 303 | 304 | ```js 305 | function App() { 306 | const onChatMessageAgent = (message) => { 307 | // place your code here 308 | } 309 | 310 | return ( 311 |
312 | 314 |
315 | ); 316 | } 317 | ``` 318 | 319 |
320 | 321 | ## onChatMessageSystem 322 | Callback function invoked when message is sent by the system. The message is passed to the function. 323 | This callback is not supported in pop out chat window. 324 | 325 | ```js 326 | function App() { 327 | const onChatMessageSystem = (message) => { 328 | // place your code here 329 | } 330 | 331 | return ( 332 |
333 | 335 |
336 | ); 337 | } 338 | ``` 339 | 340 |
341 | 342 | ## onAgentJoinChat 343 | Callback function invoked when an agent joins the chat. The data is passed to the function. Will 344 | contain {name : ”, position : ”, image : ”, id : ”}. This callback is not supported in pop out chat 345 | window. 346 | 347 | ```js 348 | function App() { 349 | const onAgentJoinChat = (data) => { 350 | // place your code here 351 | } 352 | 353 | return ( 354 |
355 | 357 |
358 | ); 359 | } 360 | ``` 361 | 362 |
363 | 364 | ## onAgentLeaveChat 365 | Callback function invoked when an agent leaves the chat. The data is passed to the function. Will 366 | contain {name : ”, id : ”}. This callback is not supported in pop out chat window. 367 | 368 | ```js 369 | function App() { 370 | const onAgentLeaveChat = (data) => { 371 | // place your code here 372 | } 373 | 374 | return ( 375 |
376 | 378 |
379 | ); 380 | } 381 | ``` 382 | 383 |
384 | 385 | ## onChatSatisfaction 386 | Callback function invoked when an agent leaves the chat. The satisfaction is passed to the function. 387 | -1 = dislike | 0 = neutral | 1 = like. This callback is not supported in pop out chat window. 388 | 389 | ```js 390 | function App() { 391 | const onChatSatisfaction = (satisfaction) => { 392 | // place your code here 393 | } 394 | 395 | return ( 396 |
397 | 399 |
400 | ); 401 | } 402 | ``` 403 | 404 |
405 | 406 | ## onVisitorNameChanged 407 | Callback function invoked when the visitor manually changes his name. The visitorName is passed to 408 | the function. This callback is not supported in pop out chat window. 409 | 410 | ```js 411 | function App() { 412 | const onVisitorNameChanged = (visitorName) => { 413 | // place your code here 414 | } 415 | 416 | return ( 417 |
418 | 420 |
421 | ); 422 | } 423 | ``` 424 | 425 |
426 | 427 | ## onFileUpload 428 | Callback function invoked when a file is uploaded. The link to the uploaded file is passed to the 429 | function. This callback is not supported in pop out chat window. 430 | 431 | ```js 432 | function App() { 433 | const onFileUpload = (link) => { 434 | // place your code here 435 | } 436 | 437 | return ( 438 |
439 | 441 |
442 | ); 443 | } 444 | ``` 445 | 446 |
447 | 448 | ## onTagsUpdated 449 | Callback function invoked when a tag is updated. 450 | 451 | ```js 452 | function App() { 453 | const onTagsUpdated = (data) => { 454 | // place your code here 455 | } 456 | 457 | return ( 458 |
459 | 461 |
462 | ); 463 | } 464 | ``` 465 | 466 |
467 | 468 | ## onUnreadCountChanged 469 | Callback function invoked when active conversation unread count changed. 470 | 471 | ```js 472 | function App() { 473 | const onUnreadCountChanged = (count) => { 474 | // place your code here 475 | } 476 | 477 | return ( 478 |
479 | 481 |
482 | ); 483 | } 484 | ``` 485 | 486 |
487 | 488 | ## onLoaded 489 | Returns a value (true or undefined) indicating when the plugin is ready. 490 | 491 | ```js 492 | tawkMessengerRef.current.onLoaded(); 493 | 494 | // Example 495 | 496 | function App() { 497 | const tawkMessengerRef = useRef(); 498 | 499 | const onLoad = () => { 500 | if (tawkMessengerRef.current.onLoaded()) { 501 | // do something before loaded 502 | } 503 | }; 504 | 505 | return ( 506 |
507 | 510 |
511 | ); 512 | } 513 | ``` 514 | 515 |
516 | 517 | ## onBeforeLoaded 518 | Returns a value (true of undefined) indicating when plugin is initialized. 519 | 520 | ```js 521 | tawkMessengerRef.current.onBeforeLoaded(); 522 | 523 | // Example 524 | 525 | function App() { 526 | const tawkMessengerRef = useRef(); 527 | 528 | const onLoad = () => { 529 | if (tawkMessengerRef.current.onBeforeLoaded()) { 530 | // do something before loaded 531 | } 532 | }; 533 | 534 | return ( 535 |
536 | 539 |
540 | ); 541 | } 542 | ``` 543 | 544 |
545 | 546 | ## widgetPosition 547 | Returns a string for current position of the widget. 548 | 549 | ```js 550 | tawkMessengerRef.current.widgetPosition(); 551 | 552 | // Example 553 | 554 | function App() { 555 | const tawkMessengerRef = useRef(); 556 | 557 | const onLoad = () => { 558 | if (tawkMessengerRef.current.widgetPosition() === 'br') { 559 | // do something if the widget is at bottom right 560 | } 561 | }; 562 | 563 | return ( 564 |
565 | 568 |
569 | ); 570 | } 571 | ``` 572 | 573 |
574 | 575 | ## visitor 576 | Object used to set the visitor name and email. Do not place this object in a function, as the 577 | values need to be available before the widget script is downloaded. 578 | 579 | Setting or changing the values after the widget script has been downloaded will not send the 580 | values to the dashboard. 581 | 582 | If the name and email will not be available on load time (eg single page app, ajax login), then 583 | use the [setAttributes](#setAttributes) function instead. 584 | 585 | ```js 586 | tawkMessengerRef.current.visitor({ 587 | name : 'name', 588 | email : 'email@email.com' 589 | }); 590 | 591 | // Example 592 | 593 | function App() { 594 | const tawkMessengerRef = useRef(); 595 | 596 | const onLoad = () => { 597 | tawkMessengerRef.current.visitor({ 598 | name : 'name', 599 | email : 'email@email.com' 600 | }); 601 | }; 602 | 603 | return ( 604 |
605 | 608 |
609 | ); 610 | } 611 | ``` 612 | 613 |
614 | 615 | ## autoStart 616 | If set to true, it will auto-start the Tawk socket connection for chat services. If set to false, 617 | you will need to manually call the start API. It will not register and connect to the dashboard 618 | if this is set to false. 619 | 620 | ```js 621 | import TawkMessengerReact from '@tawk.to/tawk-messenger-react'; 622 | 623 | function App() { 624 | return ( 625 |
626 | 630 |
631 | ); 632 | } 633 | ``` 634 | 635 |
636 | 637 | ## start 638 | Start the tawk socket connection. 639 | 640 | ```js 641 | tawkMessengerRef.current.start(); 642 | 643 | // Example 644 | 645 | function App() { 646 | const tawkMessengerRef = useRef(); 647 | 648 | const startTawk = () => { 649 | tawkMessengerRef.current.start(); 650 | }; 651 | 652 | return ( 653 |
654 | 656 |
657 | ); 658 | } 659 | ``` 660 | 661 |
662 | 663 | ## shutdown 664 | End the tawk socket connection. 665 | 666 | ```js 667 | tawkMessengerRef.current.shutdown(); 668 | 669 | // Example 670 | 671 | function App() { 672 | const tawkMessengerRef = useRef(); 673 | 674 | const shutdownTawk = () => { 675 | tawkMessengerRef.current.shutdown(); 676 | }; 677 | 678 | return ( 679 |
680 | 682 |
683 | ); 684 | } 685 | ``` 686 | 687 |
688 | 689 | ## maximize 690 | Maximizes the chat widget. 691 | 692 | ```js 693 | tawkMessengerRef.current.maximize(); 694 | 695 | // Example 696 | 697 | function App() { 698 | const tawkMessengerRef = useRef(); 699 | 700 | const onLoad = () => { 701 | tawkMessengerRef.current.maximize(); 702 | }; 703 | 704 | return ( 705 |
706 | 709 |
710 | ); 711 | } 712 | ``` 713 | 714 |
715 | 716 | ## minimize 717 | Minimizes the chat widget. 718 | 719 | ```js 720 | tawkMessengerRef.current.minimize(); 721 | 722 | // Example 723 | 724 | function App() { 725 | const tawkMessengerRef = useRef(); 726 | 727 | const onLoad = () => { 728 | tawkMessengerRef.current.minimize(); 729 | }; 730 | 731 | return ( 732 |
733 | 736 |
737 | ); 738 | } 739 | ``` 740 | 741 |
742 | 743 | ## toggle 744 | Minimizes or Maximizes the chat widget based on the current state. 745 | 746 | ```js 747 | tawkMessengerRef.current.toggle(); 748 | 749 | // Example 750 | 751 | function App() { 752 | const tawkMessengerRef = useRef(); 753 | 754 | const onLoad = () => { 755 | tawkMessengerRef.current.toggle(); 756 | }; 757 | 758 | return ( 759 |
760 | 763 |
764 | ); 765 | } 766 | ``` 767 | 768 |
769 | 770 | ## popup 771 | Opens the chat widget as a pop out. 772 | 773 | ```js 774 | tawkMessengerRef.current.popup(); 775 | 776 | // Example 777 | 778 | function App() { 779 | const tawkMessengerRef = useRef(); 780 | 781 | const onLoad = () => { 782 | tawkMessengerRef.current.popup(); 783 | }; 784 | 785 | return ( 786 |
787 | 790 |
791 | ); 792 | } 793 | ``` 794 | 795 |
796 | 797 | ## getWindowType 798 | Returns the current widget type whether it’s inline or embed. 799 | 800 | ```js 801 | tawkMessengerRef.current.getWindowType(); 802 | 803 | // Example 804 | 805 | function App() { 806 | const tawkMessengerRef = useRef(); 807 | 808 | const onLoad = () => { 809 | if (tawkMessengerRef.current.getWindowType() === 'inline') { 810 | // do something if it's inline 811 | } else { 812 | // do something if it's embed 813 | } 814 | }; 815 | 816 | return ( 817 |
818 | 821 |
822 | ); 823 | } 824 | ``` 825 | 826 |
827 | 828 | ## showWidget 829 | Shows the chat widget. 830 | 831 | ```js 832 | tawkMessengerRef.current.showWidget(); 833 | 834 | // Example 835 | 836 | function App() { 837 | const tawkMessengerRef = useRef(); 838 | 839 | const onLoad = () => { 840 | tawkMessengerRef.current.showWidget(); 841 | }; 842 | 843 | return ( 844 |
845 | 848 |
849 | ); 850 | } 851 | ``` 852 | 853 |
854 | 855 | ## hideWidget 856 | Hide the chat widget. 857 | 858 | ```js 859 | tawkMessengerRef.current.hideWidget(); 860 | 861 | // Example 862 | 863 | function App() { 864 | const tawkMessengerRef = useRef(); 865 | 866 | const onLoad = () => { 867 | tawkMessengerRef.current.hideWidget(); 868 | }; 869 | 870 | return ( 871 |
872 | 875 |
876 | ); 877 | } 878 | ``` 879 | 880 |
881 | 882 | ## toggleVisibility 883 | Hides or Shows the chat widget based on the current visibility state. 884 | 885 | ```js 886 | tawkMessengerRef.current.toggeVisibility(); 887 | 888 | // Example 889 | 890 | function App() { 891 | const tawkMessengerRef = useRef(); 892 | 893 | const onLoad = () => { 894 | tawkMessengerRef.current.toggeVisibility(); 895 | }; 896 | 897 | return ( 898 |
899 | 902 |
903 | ); 904 | } 905 | ``` 906 | 907 |
908 | 909 | ## getStatus 910 | Returns the current page status (online, away or offline). 911 | 912 | ```js 913 | tawkMessengerRef.current.getStatus(); 914 | 915 | // Example 916 | 917 | function App() { 918 | const tawkMessengerRef = useRef(); 919 | 920 | const onLoad = () => { 921 | const pageStatus = tawkMessengerRef.current.getStatus(); 922 | 923 | if (pageStatus === 'online') { 924 | // do something for online 925 | } else if (pageStatus === 'away') { 926 | // do something for away 927 | } else { 928 | // do something for offline 929 | } 930 | }; 931 | 932 | return ( 933 |
934 | 937 |
938 | ); 939 | } 940 | ``` 941 | 942 |
943 | 944 | ## isChatMaximized 945 | Returns a boolean value (true or false) indicating whether the chat widget is maximized. 946 | 947 | ```js 948 | tawkMessengerRef.current.isChatMaximized(); 949 | 950 | // Example 951 | 952 | function App() { 953 | const tawkMessengerRef = useRef(); 954 | 955 | const onLoad = () => { 956 | if (tawkMessengerRef.current.isChatMaximized()) { 957 | // do something if it's maximized 958 | } 959 | }; 960 | 961 | return ( 962 |
963 | 966 |
967 | ); 968 | } 969 | ``` 970 | 971 |
972 | 973 | ## isChatMinimized 974 | Returns a boolean value (true or false) indicating whether the chat widget is minimized. 975 | 976 | ```js 977 | tawkMessengerRef.current.isChatMinimized(); 978 | 979 | // Example 980 | 981 | function App() { 982 | const tawkMessengerRef = useRef(); 983 | 984 | const onLoad = () => { 985 | if (tawkMessengerRef.current.isChatMinimized()) { 986 | // do something if it's minimized 987 | } 988 | }; 989 | 990 | return ( 991 |
992 | 995 |
996 | ); 997 | } 998 | ``` 999 | 1000 |
1001 | 1002 | ## isChatHidden 1003 | Returns a boolean value (true or false) indicating whether the chat widget is hidden. 1004 | 1005 | ```js 1006 | tawkMessengerRef.current.isChatHidden(); 1007 | 1008 | // Example 1009 | 1010 | function App() { 1011 | const tawkMessengerRef = useRef(); 1012 | 1013 | const onLoad = () => { 1014 | if (tawkMessengerRef.current.isChatHidden()) { 1015 | // do something if chat widget is hidden 1016 | } 1017 | }; 1018 | 1019 | return ( 1020 |
1021 | 1024 |
1025 | ); 1026 | } 1027 | ``` 1028 | 1029 |
1030 | 1031 | ## isChatOngoing 1032 | Returns a boolean value (true or false) indicating whether currently there is an ongoing chat. 1033 | 1034 | ```js 1035 | tawkMessengerRef.current.isChatOngoing(); 1036 | 1037 | // Example 1038 | 1039 | function App() { 1040 | const tawkMessengerRef = useRef(); 1041 | 1042 | const onLoad = () => { 1043 | if (tawkMessengerRef.current.isChatOngoing()) { 1044 | // do something if there's ongoing chat 1045 | } 1046 | }; 1047 | 1048 | return ( 1049 |
1050 | 1053 |
1054 | ); 1055 | } 1056 | ``` 1057 | 1058 |
1059 | 1060 | ## isVisitorEngaged 1061 | Returns a boolean value (true or false) indicating whether the visitor is currently chatting or has 1062 | requested a chat. 1063 | 1064 | ```js 1065 | tawkMessengerRef.current.isVisitorEngaged(); 1066 | 1067 | // Example 1068 | 1069 | function App() { 1070 | const tawkMessengerRef = useRef(); 1071 | 1072 | const onLoad = () => { 1073 | if (tawkMessengerRef.current.isVisitorEngaged()) { 1074 | // do something if visitor engaged in chat 1075 | } 1076 | }; 1077 | 1078 | return ( 1079 |
1080 | 1083 |
1084 | ); 1085 | } 1086 | ``` 1087 | 1088 |
1089 | 1090 | ## endChat 1091 | Ends the current ongoing chat. 1092 | 1093 | ```js 1094 | tawkMessengerRef.current.endChat(); 1095 | 1096 | // Example 1097 | 1098 | function App() { 1099 | const tawkMessengerRef = useRef(); 1100 | 1101 | const onLoad = () => { 1102 | tawkMessengerRef.current.endChat(); 1103 | }; 1104 | 1105 | return ( 1106 |
1107 | 1110 |
1111 | ); 1112 | } 1113 | ``` 1114 | 1115 |
1116 | 1117 | ## setAttributes 1118 | Set custom metadata regarding this chat/visitor. 1119 | 1120 | This function takes in two values: attribute and callback. 1121 | 1122 | The attribute value is of the object data type, which is a key value pair. 1123 | 1124 | The key is of the string data type and can contain only alphanumeric characters and ‘-‘ (dash). 1125 | 1126 | You can also use this function to set the visitor name and email. However, you will need to enable 1127 | the secure mode first and also supply the calculated hash value in this function. 1128 | 1129 | Refer to the secure mode section below on how to do this. 1130 | 1131 | The reason it needs to be in [secure mode](#securemode) is to ensure data integrity — to ensure the 1132 | value sent from the widget to the dashboard is true and has not been tampered with. 1133 | 1134 | The callback, which is a function, will be invoked to notify whether the save failed. 1135 | 1136 | Error messages returned: 1137 | 1138 | 1. INVALID_ATTRIBUTES: No attributes were sent 1139 | 1. SESSION_EXPIRED: The visitor’s current session has expired 1140 | 1. SERVER_ERROR: Internal server error 1141 | 1. ACCESS_ERROR: Error in accessing the page 1142 | 1. ATTRIBUTE_LIMIT_EXCEEDED: Total custom attributes (excluding name, email and hash) is 50 1143 | 1. CONTAINS_INVALID_KEY: Custom key is not alphanumeric or dash (keys will be lower case) 1144 | 1. CONTAINS_INVALID_VALUE: Custom value is empty or the total length is more than 255 characters 1145 | 1146 | ```js 1147 | tawkMessengerRef.current.setAttributes(attributes, callback); 1148 | 1149 | // Example 1150 | 1151 | function App() { 1152 | const tawkMessengerRef = useRef(); 1153 | 1154 | const onLoad = () => { 1155 | tawkMessengerRef.current.setAttributes({ 1156 | id : 'A1234', 1157 | store : 'Midvalley' 1158 | }, function(error) { 1159 | // do something if error 1160 | }); 1161 | 1162 | // Example for setting name and email 1163 | 1164 | tawkMessengerRef.current.setAttributes({ 1165 | name : 'name', 1166 | store : 'name@email.com', 1167 | hash : 'has value' 1168 | }, function(error) { 1169 | // do something if error 1170 | }); 1171 | }; 1172 | 1173 | return ( 1174 |
1175 | 1178 |
1179 | ); 1180 | } 1181 | ``` 1182 | 1183 |
1184 | 1185 | ## addEvent 1186 | Set a custom event to chat. 1187 | This function takes in 3 values: event name, optional metadata and callback. 1188 | 1189 | The event name is of the string data type and can contain only alphanumeric characters and ‘-‘ (dash) 1190 | 1191 | The callback which is a function will be invoked to notify whether the save failed. 1192 | 1193 | INVALID_EVENT_NAME, INVALID_ATTRIBUTES, ATTRIBUTE_LIMIT_EXCEEDED, CONTAINS_INVALID_KEY, 1194 | CONTAINS_INVALID_VALUE, SESSION_EXPIRED, SERVER_ERROR 1195 | 1196 | ```js 1197 | tawkMessengerRef.current.addEvent(eventName, metaData, callback); 1198 | 1199 | // Example 1200 | 1201 | function App() { 1202 | const tawkMessengerRef = useRef(); 1203 | 1204 | const onLoad = () => { 1205 | tawkMessengerRef.current.addEvent( 1206 | 'requested-quotation', 1207 | function(error) { 1208 | // do something if error 1209 | } 1210 | ); 1211 | 1212 | // Example with metadata 1213 | 1214 | tawkMessengerRef.current.addEvent( 1215 | 'requested-quotation', 1216 | { 1217 | sku : 'A0012', 1218 | name : 'Jeans', 1219 | price : '50' 1220 | } 1221 | function(error) { 1222 | // do something if error 1223 | } 1224 | ); 1225 | }; 1226 | 1227 | return ( 1228 |
1229 | 1232 |
1233 | ); 1234 | } 1235 | ``` 1236 | 1237 |
1238 | 1239 | ## addTags 1240 | Add tags to the chat. 1241 | This function takes in two values; tags and callback. 1242 | This is of the array data type. 1243 | The content of the tags should be of the string data type. 1244 | 1245 | The total number of tags is 10. 1246 | The callback, which is a function, will be invoked to notify whether the save failed. 1247 | 1248 | INVALID_TAGS, TAG_LIMIT_EXCEEDED, VERSION_CONFLICT, SESSION_EXPIRED, SERVER_ERROR 1249 | 1250 | ```js 1251 | tawkMessengerRef.current.addTags(tags, callback); 1252 | 1253 | // Example 1254 | 1255 | function App() { 1256 | const tawkMessengerRef = useRef(); 1257 | 1258 | const onLoad = () => { 1259 | tawkMessengerRef.current.addTags( 1260 | [ 1261 | 'hello', 1262 | 'world' 1263 | ], 1264 | function(error) { 1265 | // do something if error 1266 | } 1267 | ); 1268 | }; 1269 | 1270 | return ( 1271 |
1272 | 1275 |
1276 | ); 1277 | } 1278 | ``` 1279 | 1280 |
1281 | 1282 | ## removeTags 1283 | Remove tags from the chat. 1284 | This function takes in two values: tags and callback. 1285 | This is of the array data type. 1286 | The content of the tags should be of the string data type. 1287 | 1288 | The callback, which is a function, will be invoked to notify whether the save failed. 1289 | 1290 | INVALID_TAGS, TAG_LIMIT_EXCEEDED, SESSION_EXPIRED, SERVER_ERROR 1291 | 1292 | ```js 1293 | tawkMessengerRef.current.removeTags(tags, callback); 1294 | 1295 | // Example 1296 | 1297 | function App() { 1298 | const tawkMessengerRef = useRef(); 1299 | 1300 | const onLoad = () => { 1301 | tawkMessengerRef.current.removeTags( 1302 | [ 1303 | 'hello', 1304 | 'world' 1305 | ], 1306 | function(error) { 1307 | // do something if error 1308 | } 1309 | ); 1310 | }; 1311 | 1312 | return ( 1313 |
1314 | 1317 |
1318 | ); 1319 | } 1320 | ``` 1321 | 1322 |
1323 | 1324 | ## secureMode 1325 | Secure method is to ensure the data you are sending is actually from you. 1326 | 1327 | To enable secure mode, embed following code on your page. 1328 | 1329 | The hash is server side generated HMAC using SHA256, the user’s email and your site’s API key. 1330 | 1331 | You can get your API key from **Admin>Property Settings**. 1332 | 1333 | ```js 1334 | tawkMessengerRef.current.visitor({ 1335 | name : 'name', 1336 | email : 'email@email.com' 1337 | hash : '' 1338 | }); 1339 | ``` 1340 | 1341 | ## switchWidget 1342 | Disconnect the current widget connection, logout if it has existing user login and switch to 1343 | another widget. 1344 | 1345 | ```js 1346 | tawkMessengerRef.current.switchWidget(options); 1347 | 1348 | // Example 1349 | 1350 | function App() { 1351 | const tawkMessengerRef = useRef(); 1352 | 1353 | const onLoad = () => { 1354 | tawkMessengerRef.current.switchWidget({ 1355 | propertyId ; 'property_id', 1356 | widgetId : 'widget_id' 1357 | }, function() { 1358 | // do something 1359 | }); 1360 | }; 1361 | 1362 | return ( 1363 |
1364 | 1367 |
1368 | ); 1369 | } 1370 | ``` 1371 | 1372 | ## customstyle 1373 | Object used to update the widget styling. Currently only supports zIndex style. Do not place this 1374 | object in a function, as the values need to be available before the widget script is downloaded. 1375 | Setting or changing the values after the widget script has been downloaded will not update the 1376 | widget’s style. 1377 | 1378 | ### zIndex 1379 | ```js 1380 | 1382 | 1383 | // Example 1384 | 1385 | function App() { 1386 | return ( 1387 |
1388 | 1390 |
1391 | ); 1392 | } 1393 | 1394 | function App() { 1395 | return ( 1396 |
1397 | 1399 |
1400 | ); 1401 | } 1402 | 1403 | function App() { 1404 | return ( 1405 |
1406 | 1408 |
1409 | ); 1410 | } 1411 | ``` 1412 | 1413 |
1414 | 1415 | ### Visibility 1416 | ```js 1417 | const customStyle = { 1418 | visibility : { 1419 | desktop : { 1420 | xOffset : String | Integer, // '20' || 20 1421 | yOffset : String | Integer, 1422 | position : '' // 'br', 'bl', 'cr', 'cl', 'tr', 'tl' 1423 | }, 1424 | 1425 | mobile : { 1426 | xOffset : String | Integer, // '20' || 20 1427 | yOffset : String | Integer, 1428 | position : '' // 'br', 'bl', 'cr', 'cl', 'tr', 'tl' 1429 | } 1430 | } 1431 | }; 1432 | 1433 | return ( 1434 | 1436 | ); 1437 | 1438 | // Example 1439 | 1440 | const customStyle = { 1441 | visibility : { 1442 | desktop : { 1443 | xOffset : '15', 1444 | yOffset : '15', 1445 | position : 'cr' 1446 | }, 1447 | 1448 | mobile : { 1449 | xOffset : 15, 1450 | yOffset : 15, 1451 | position : 'bl' 1452 | } 1453 | } 1454 | }; 1455 | 1456 | return ( 1457 | 1459 | ); 1460 | ``` -------------------------------------------------------------------------------- /docs/how-to-use.md: -------------------------------------------------------------------------------- 1 | # How to Use 2 | Here are the basic of how to use callbacks and expose functions from the plugin. You can see the 3 | list of APIs in this [API reference](api-reference.md). 4 | 5 | ## Expose functions 6 | To access the expose functions, you will need to use **useRef** from react. Create a constant 7 | variable that will hold the **useRef()** and pass it in **TawkMessengerReact** component as a prop. 8 | 9 | ```js 10 | import { useRef } from 'react'; 11 | import TawkMessengerReact from '@tawk.to/tawk-messenger-react'; 12 | 13 | function App() { 14 | const tawkMessengerRef = useRef(); 15 | 16 | const handleMinimize = () => { 17 | tawkMessengerRef.current.minimize(); 18 | }; 19 | 20 | return ( 21 |
22 | 23 | 24 | 28 |
29 | ); 30 | } 31 | ``` 32 | 33 | ## Using Callbacks 34 | Using the API callbacks, pass a function as props on the callback you will used. 35 | 36 | ```js 37 | function App() { 38 | const onLoad = () => { 39 | console.log('onLoad works!'); 40 | }; 41 | 42 | return ( 43 |
44 | 48 |
49 | ); 50 | } 51 | ``` 52 | 53 | -------------------------------------------------------------------------------- /images/tawk-react-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tawk/tawk-messenger-react/8fcd369bfc091391a7c7600ce6421df583916803/images/tawk-react-logo.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tawk.to/tawk-messenger-react", 3 | "version": "2.0.2", 4 | "description": "Official React plugin for Tawk messenger", 5 | "keywords": [ 6 | "react", 7 | "reactjs", 8 | "next", 9 | "react-plugin", 10 | "tawk", 11 | "next-plugin", 12 | "tawkto", 13 | "react-tawk", 14 | "next-tawk" 15 | ], 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/tawk/tawk-messenger-react.git", 19 | "repository": "tawk/tawk-messenger-react" 20 | }, 21 | "homepage": "https://github.com/tawk/tawk-messenger-react#readme", 22 | "bugs": { 23 | "url": "https://github.com/tawk/tawk-messenger-react/issues", 24 | "email": "support@tawk.to" 25 | }, 26 | "license": "Apache-2.0", 27 | "author": "Jerald Austero (https://www.tawk.to)", 28 | "files": [ 29 | "dist" 30 | ], 31 | "main": "./dist/tawk-messenger-react.umd.js", 32 | "module": "./dist/tawk-messenger-react.es.js", 33 | "exports": { 34 | ".": { 35 | "import": "./dist/tawk-messenger-react.es.js", 36 | "require": "./dist/tawk-messenger-react.umd.js" 37 | } 38 | }, 39 | "scripts": { 40 | "build": "vite build", 41 | "test": "react-scripts test", 42 | "lint": "eslint src/**/*.js" 43 | }, 44 | "peerDependencies": { 45 | "react": "^18.1.0", 46 | "react-dom": "^18.1.0" 47 | }, 48 | "devDependencies": { 49 | "@testing-library/jest-dom": "^5.16.4", 50 | "@testing-library/react": "^13.2.0", 51 | "@testing-library/user-event": "^14.1.1", 52 | "@vitejs/plugin-react": "^1.3.2", 53 | "babel-eslint": "^10.1.0", 54 | "eslint-plugin-jest": "^26.1.5", 55 | "eslint-plugin-react": "^7.29.4", 56 | "react": "^18.1.0", 57 | "react-dom": "^18.1.0", 58 | "react-scripts": "^5.0.1", 59 | "vite": "^2.9.9" 60 | }, 61 | "eslintConfig": { 62 | "extends": [ 63 | "react-app", 64 | "react-app/jest" 65 | ] 66 | }, 67 | "browserslist": { 68 | "production": [ 69 | ">0.2%", 70 | "not dead", 71 | "not op_mini all" 72 | ], 73 | "development": [ 74 | "last 1 chrome version", 75 | "last 1 firefox version", 76 | "last 1 safari version" 77 | ] 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/__tests__/Install.spec.js: -------------------------------------------------------------------------------- 1 | /* global document */ 2 | 3 | // Dependecy 4 | import { unmountComponentAtNode } from 'react-dom'; 5 | import { render, act } from '@testing-library/react'; 6 | 7 | // Plugin 8 | import TawkMessengerReact from '../index'; 9 | 10 | 11 | let container = null; 12 | jest.spyOn(console, 'error').mockReturnValue(true); 13 | 14 | 15 | describe('Install tawk-messenger-react', () => { 16 | beforeEach(() => { 17 | container = document.createElement('script'); 18 | document.body.appendChild(container); 19 | }); 20 | 21 | afterEach(() => { 22 | unmountComponentAtNode(container); 23 | container.remove(); 24 | container = null; 25 | }); 26 | 27 | describe('Should throw an error in missing required properties', () => { 28 | it('when propertyId and widgetId are not defined', () => { 29 | act(() => { 30 | render(, container); 31 | }); 32 | 33 | /** 34 | * 1st error - PropType 'propertyId' is required 35 | * 2nd error - PropType 'widgetId' is required 36 | * 3rd error - Custom log from load() 37 | */ 38 | expect(console.error).toHaveBeenCalledTimes(3); 39 | }); 40 | 41 | it('when widgetId only is not defined', () => { 42 | act(() => { 43 | render( 44 | , 46 | container 47 | ); 48 | }); 49 | 50 | /** 51 | * 1st error - PropType 'widgetId' is required 52 | */ 53 | expect(console.error).toHaveBeenCalledTimes(1); 54 | }); 55 | 56 | it('when propertId only is not defined', () => { 57 | act(() => { 58 | render( 59 | , 61 | container 62 | ); 63 | }); 64 | 65 | /** 66 | * 1st error - PropType 'widgetId' is required 67 | */ 68 | expect(console.error).toHaveBeenCalledTimes(1); 69 | }); 70 | }); 71 | }); -------------------------------------------------------------------------------- /src/__tests__/TawkMessenger.spec.js: -------------------------------------------------------------------------------- 1 | /* global document, window */ 2 | 3 | // Dependecy 4 | import { unmountComponentAtNode } from 'react-dom'; 5 | import { render, act } from '@testing-library/react'; 6 | 7 | // Plugin 8 | import TawkMessengerReact from '../index'; 9 | 10 | 11 | let container = null; 12 | jest.spyOn(window, 'addEventListener'); 13 | 14 | 15 | describe('Tawk-messenger plugin', () => { 16 | beforeEach(() => { 17 | container = document.createElement('script'); 18 | document.body.appendChild(container); 19 | }); 20 | 21 | afterEach(() => { 22 | unmountComponentAtNode(container); 23 | container.remove(); 24 | container = null; 25 | }); 26 | 27 | describe('Initialize plugin', () => { 28 | it('should have global variable \'Tawk_API\'', () => { 29 | act(() => { 30 | render( 31 | , 34 | container 35 | ); 36 | }); 37 | 38 | expect(typeof window.Tawk_API === 'object').toBe(true); 39 | }); 40 | 41 | it('should set \'customStyle\' property in \'Tawk_API\'', () => { 42 | act(() => { 43 | render( 44 | , 48 | container 49 | ); 50 | }); 51 | 52 | expect(typeof window.Tawk_API.customStyle === 'object').toBe(true); 53 | }); 54 | }); 55 | 56 | describe('API', () => { 57 | it('should set the action functions', () => { 58 | const tawkMessengerRef = { 59 | current : {} 60 | }; 61 | 62 | act(() => { 63 | render( 64 | , 68 | container 69 | ); 70 | }); 71 | 72 | expect(typeof tawkMessengerRef.current.maximize === 'function').toBe(true); 73 | expect(typeof tawkMessengerRef.current.minimize === 'function').toBe(true); 74 | expect(typeof tawkMessengerRef.current.toggle === 'function').toBe(true); 75 | expect(typeof tawkMessengerRef.current.popup === 'function').toBe(true); 76 | expect(typeof tawkMessengerRef.current.showWidget === 'function').toBe(true); 77 | expect(typeof tawkMessengerRef.current.hideWidget === 'function').toBe(true); 78 | expect(typeof tawkMessengerRef.current.toggleVisibility === 'function').toBe(true); 79 | expect(typeof tawkMessengerRef.current.endChat === 'function').toBe(true); 80 | }); 81 | 82 | it('should set the getters functions', () => { 83 | const tawkMessengerRef = { 84 | current : {} 85 | }; 86 | 87 | act(() => { 88 | render( 89 | , 93 | container 94 | ); 95 | }); 96 | 97 | expect(typeof tawkMessengerRef.current.getWindowType === 'function').toBe(true); 98 | expect(typeof tawkMessengerRef.current.getStatus === 'function').toBe(true); 99 | expect(typeof tawkMessengerRef.current.isChatMaximized === 'function').toBe(true); 100 | expect(typeof tawkMessengerRef.current.isChatMinimized === 'function').toBe(true); 101 | expect(typeof tawkMessengerRef.current.isChatHidden === 'function').toBe(true); 102 | expect(typeof tawkMessengerRef.current.isChatOngoing === 'function').toBe(true); 103 | expect(typeof tawkMessengerRef.current.isVisitorEngaged === 'function').toBe(true); 104 | expect(typeof tawkMessengerRef.current.onLoaded === 'function').toBe(true); 105 | expect(typeof tawkMessengerRef.current.onBeforeLoaded === 'function').toBe(true); 106 | expect(typeof tawkMessengerRef.current.widgetPosition === 'function').toBe(true); 107 | }); 108 | 109 | it('should set the event functions', () => { 110 | act(() => { 111 | render( 112 | , 115 | container 116 | ); 117 | }); 118 | 119 | expect(window.addEventListener).toHaveBeenCalledWith('tawkLoad', expect.any(Function)); 120 | expect(window.addEventListener).toHaveBeenCalledWith('tawkStatusChange', expect.any(Function)); 121 | expect(window.addEventListener).toHaveBeenCalledWith('tawkBeforeLoad', expect.any(Function)); 122 | expect(window.addEventListener).toHaveBeenCalledWith('tawkChatMaximized', expect.any(Function)); 123 | expect(window.addEventListener).toHaveBeenCalledWith('tawkChatMinimized', expect.any(Function)); 124 | expect(window.addEventListener).toHaveBeenCalledWith('tawkChatHidden', expect.any(Function)); 125 | expect(window.addEventListener).toHaveBeenCalledWith('tawkChatStarted', expect.any(Function)); 126 | expect(window.addEventListener).toHaveBeenCalledWith('tawkChatEnded', expect.any(Function)); 127 | expect(window.addEventListener).toHaveBeenCalledWith('tawkPrechatSubmit', expect.any(Function)); 128 | expect(window.addEventListener).toHaveBeenCalledWith('tawkOfflineSubmit', expect.any(Function)); 129 | expect(window.addEventListener).toHaveBeenCalledWith('tawkChatMessageVisitor', expect.any(Function)); 130 | expect(window.addEventListener).toHaveBeenCalledWith('tawkChatMessageAgent', expect.any(Function)); 131 | expect(window.addEventListener).toHaveBeenCalledWith('tawkChatMessageSystem', expect.any(Function)); 132 | expect(window.addEventListener).toHaveBeenCalledWith('tawkAgentJoinChat', expect.any(Function)); 133 | expect(window.addEventListener).toHaveBeenCalledWith('tawkAgentLeaveChat', expect.any(Function)); 134 | expect(window.addEventListener).toHaveBeenCalledWith('tawkChatSatisfaction', expect.any(Function)); 135 | expect(window.addEventListener).toHaveBeenCalledWith('tawkVisitorNameChanged', expect.any(Function)); 136 | expect(window.addEventListener).toHaveBeenCalledWith('tawkFileUpload', expect.any(Function)); 137 | expect(window.addEventListener).toHaveBeenCalledWith('tawkTagsUpdated', expect.any(Function)); 138 | expect(window.addEventListener).toHaveBeenCalledWith('tawkUnreadCountChanged', expect.any(Function)); 139 | }); 140 | 141 | it('should set the setter functions', () => { 142 | const tawkMessengerRef = { 143 | current : {} 144 | }; 145 | 146 | act(() => { 147 | render( 148 | , 152 | container 153 | ); 154 | }); 155 | 156 | expect(typeof tawkMessengerRef.current.visitor === 'function').toBe(true); 157 | expect(typeof tawkMessengerRef.current.setAttributes === 'function').toBe(true); 158 | expect(typeof tawkMessengerRef.current.addEvent === 'function').toBe(true); 159 | expect(typeof tawkMessengerRef.current.addTags === 'function').toBe(true); 160 | expect(typeof tawkMessengerRef.current.removeTags === 'function').toBe(true); 161 | }); 162 | }); 163 | }); -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /* global window, document */ 2 | 3 | // Dependencies 4 | import { forwardRef, useEffect, useImperativeHandle } from 'react'; 5 | import PropTypes from 'prop-types'; 6 | 7 | // Helper 8 | import { isValidString } from './utils/helper'; 9 | import { loadScript } from './utils/widget'; 10 | 11 | const TawkMessenger = forwardRef((props, ref) => { 12 | useEffect(() => { 13 | load(); 14 | }, []); 15 | 16 | const load = () => { 17 | if (!isValidString(props.propertyId)) { 18 | console.error('[Tawk-messenger-react warn]: You didn\'t specified \'propertyId\' property in the plugin.'); 19 | return; 20 | } 21 | 22 | if (!isValidString(props.widgetId)) { 23 | console.error('[Tawk-messenger-react warn]: You didn\'t specified \'widgetId\' property in the plugin.'); 24 | return; 25 | } 26 | 27 | if (!window || !document) { 28 | return; 29 | } 30 | 31 | init(); 32 | }; 33 | 34 | const init = () => { 35 | /** 36 | * Set placeholder 37 | */ 38 | window.Tawk_API = window.Tawk_API || {}; 39 | window.Tawk_LoadStart = new Date(); 40 | 41 | /** 42 | * Inject the Tawk script 43 | */ 44 | loadScript({ 45 | propertyId : props.propertyId, 46 | widgetId : props.widgetId, 47 | embedId : props.embedId, 48 | basePath : props.basePath, 49 | autoStart : props.autoStart 50 | }); 51 | 52 | /** 53 | * Set custom style 54 | */ 55 | if (props.customStyle && typeof props.customStyle === 'object') { 56 | window.Tawk_API.customStyle = props.customStyle; 57 | } 58 | 59 | mapCallbacks(); 60 | }; 61 | 62 | useImperativeHandle(ref, () => ({ 63 | /** 64 | * API for calling an action on the widget 65 | */ 66 | start : () => { 67 | return window.Tawk_API.start(); 68 | }, 69 | 70 | shutdown : () => { 71 | return window.Tawk_API.shutdown(); 72 | }, 73 | 74 | maximize : () => { 75 | return window.Tawk_API.maximize(); 76 | }, 77 | 78 | minimize : () => { 79 | return window.Tawk_API.minimize(); 80 | }, 81 | 82 | toggle : () => { 83 | return window.Tawk_API.toggle(); 84 | }, 85 | 86 | popup : () => { 87 | return window.Tawk_API.popup(); 88 | }, 89 | 90 | showWidget : () => { 91 | return window.Tawk_API.showWidget(); 92 | }, 93 | 94 | hideWidget : () => { 95 | return window.Tawk_API.hideWidget(); 96 | }, 97 | 98 | toggleVisibility : () => { 99 | return window.Tawk_API.toggleVisibility(); 100 | }, 101 | 102 | endChat : () => { 103 | return window.Tawk_API.endChat(); 104 | }, 105 | 106 | 107 | /** 108 | * API for returning a data 109 | */ 110 | getWindowType : () => { 111 | return window.Tawk_API.getWindowType(); 112 | }, 113 | 114 | getStatus : () => { 115 | return window.Tawk_API.getStatus(); 116 | }, 117 | 118 | isChatMaximized : () => { 119 | return window.Tawk_API.isChatMaximized(); 120 | }, 121 | 122 | isChatMinimized : () => { 123 | return window.Tawk_API.isChatMinimized(); 124 | }, 125 | 126 | isChatHidden : () => { 127 | return window.Tawk_API.isChatHidden(); 128 | }, 129 | 130 | isChatOngoing : () => { 131 | return window.Tawk_API.isChatOngoing(); 132 | }, 133 | 134 | isVisitorEngaged : () => { 135 | return window.Tawk_API.isVisitorEngaged(); 136 | }, 137 | 138 | onLoaded : () => { 139 | return window.Tawk_API.onLoaded; 140 | }, 141 | 142 | onBeforeLoaded : () => { 143 | return window.Tawk_API.onBeforeLoaded; 144 | }, 145 | 146 | widgetPosition : () => { 147 | return window.Tawk_API.widgetPosition(); 148 | }, 149 | 150 | 151 | /** 152 | * API for setting a data on the widget 153 | */ 154 | visitor : (data) => { 155 | window.Tawk_API.visitor = data; 156 | }, 157 | 158 | setAttributes : (attribute, callback) => { 159 | window.Tawk_API.setAttributes(attribute, callback); 160 | }, 161 | 162 | addEvent : (event, metadata, callback) => { 163 | window.Tawk_API.addEvent(event, metadata, callback); 164 | }, 165 | 166 | addTags : (tags, callback) => { 167 | window.Tawk_API.addTags(tags, callback); 168 | }, 169 | 170 | removeTags : (tags, callback) => { 171 | window.Tawk_API.removeTags(tags, callback); 172 | }, 173 | 174 | switchWidget : (options, callback) => { 175 | window.Tawk_API.switchWidget(data, callback); 176 | } 177 | })); 178 | 179 | /** 180 | * API for listening an event emitting 181 | * inside of the widget 182 | */ 183 | const mapCallbacks = () => { 184 | window.addEventListener('tawkLoad', () => { 185 | props.onLoad(); 186 | }); 187 | 188 | window.addEventListener('tawkStatusChange', (status) => { 189 | props.onStatusChange(status.detail); 190 | }); 191 | 192 | window.addEventListener('tawkBeforeLoad', () => { 193 | props.onBeforeLoad(); 194 | }); 195 | 196 | window.addEventListener('tawkChatMaximized', () => { 197 | props.onChatMaximized(); 198 | }); 199 | 200 | window.addEventListener('tawkChatMinimized', () => { 201 | props.onChatMinimized(); 202 | }); 203 | 204 | window.addEventListener('tawkChatHidden', () => { 205 | props.onChatHidden(); 206 | }); 207 | 208 | window.addEventListener('tawkChatStarted', () => { 209 | props.onChatStarted(); 210 | }); 211 | 212 | window.addEventListener('tawkChatEnded', () => { 213 | props.onChatEnded(); 214 | }); 215 | 216 | window.addEventListener('tawkPrechatSubmit', (data) => { 217 | props.onPrechatSubmit(data.detail); 218 | }); 219 | 220 | window.addEventListener('tawkOfflineSubmit', (data) => { 221 | props.onOfflineSubmit(data.detail); 222 | }); 223 | 224 | window.addEventListener('tawkChatMessageVisitor', (message) => { 225 | props.onChatMessageVisitor(message.detail); 226 | }); 227 | 228 | window.addEventListener('tawkChatMessageAgent', (message) => { 229 | props.onChatMessageAgent(message.detail); 230 | }); 231 | 232 | window.addEventListener('tawkChatMessageSystem', (message) => { 233 | props.onChatMessageSystem(message.detail); 234 | }); 235 | 236 | window.addEventListener('tawkAgentJoinChat', (data) => { 237 | props.onAgentJoinChat(data.detail); 238 | }); 239 | 240 | window.addEventListener('tawkAgentLeaveChat', (data) => { 241 | props.onAgentLeaveChat(data.detail); 242 | }); 243 | 244 | window.addEventListener('tawkChatSatisfaction', (satisfaction) => { 245 | props.onChatSatisfaction(satisfaction.detail); 246 | }); 247 | 248 | window.addEventListener('tawkVisitorNameChanged', (visitorName) => { 249 | props.onVisitorNameChanged(visitorName.detail); 250 | }); 251 | 252 | window.addEventListener('tawkFileUpload', (link) => { 253 | props.onFileUpload(link.detail); 254 | }); 255 | 256 | window.addEventListener('tawkTagsUpdated', (data) => { 257 | props.onTagsUpdated(data.detail); 258 | }); 259 | 260 | window.addEventListener('tawkUnreadCountChanged', (data) => { 261 | props.onUnreadCountChanged(data.detail); 262 | }); 263 | }; 264 | 265 | return null; 266 | }); 267 | 268 | TawkMessenger.displayName = 'TawkMessenger'; 269 | 270 | TawkMessenger.defaultProps = { 271 | customStyle : null, 272 | embedId : '', 273 | basePath : 'tawk.to', 274 | onLoad : () => {}, 275 | onStatusChange : () => {}, 276 | onBeforeLoad : () => {}, 277 | onChatMaximized : () => {}, 278 | onChatMinimized : () => {}, 279 | onChatHidden : () => {}, 280 | onChatStarted : () => {}, 281 | onChatEnded : () => {}, 282 | onPrechatSubmit : () => {}, 283 | onOfflineSubmit : () => {}, 284 | onChatMessageVisitor : () => {}, 285 | onChatMessageAgent : () => {}, 286 | onChatMessageSystem : () => {}, 287 | onAgentJoinChat : () => {}, 288 | onAgentLeaveChat : () => {}, 289 | onChatSatisfaction : () => {}, 290 | onVisitorNameChanged : () => {}, 291 | onFileUpload : () => {}, 292 | onTagsUpdated : () => {}, 293 | onUnreadCountChanged : () => {} 294 | }; 295 | 296 | 297 | TawkMessenger.propTypes = { 298 | /** 299 | * Default properties 300 | */ 301 | propertyId : PropTypes.string.isRequired, 302 | widgetId : PropTypes.string.isRequired, 303 | 304 | /** 305 | * Optional properties 306 | */ 307 | customStyle : PropTypes.object, 308 | embedId : PropTypes.string, 309 | basePath : PropTypes.string, 310 | 311 | /** 312 | * Callbacks 313 | */ 314 | onLoad : PropTypes.func, 315 | onStatusChange : PropTypes.func, 316 | onBeforeLoad : PropTypes.func, 317 | onChatMaximized : PropTypes.func, 318 | onChatMinimized : PropTypes.func, 319 | onChatHidden : PropTypes.func, 320 | onChatStarted : PropTypes.func, 321 | onChatEnded : PropTypes.func, 322 | onPrechatSubmit : PropTypes.func, 323 | onOfflineSubmit : PropTypes.func, 324 | onChatMessageVisitor : PropTypes.func, 325 | onChatMessageAgent : PropTypes.func, 326 | onChatMessageSystem : PropTypes.func, 327 | onAgentJoinChat : PropTypes.func, 328 | onAgentLeaveChat : PropTypes.func, 329 | onChatSatisfaction : PropTypes.func, 330 | onVisitorNameChanged : PropTypes.func, 331 | onFileUpload : PropTypes.func, 332 | onTagsUpdated : PropTypes.func, 333 | onUnreadCountChanged : PropTypes.func 334 | }; 335 | 336 | 337 | export default TawkMessenger; -------------------------------------------------------------------------------- /src/utils/helper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {String} value - A data that needs to be validated 3 | * @returns - Boolean 4 | */ 5 | const isValidString = (value) => { 6 | if (!value || value.length === 0) { 7 | return false; 8 | } 9 | 10 | return value !== null && value !== undefined && typeof value === 'string'; 11 | }; 12 | 13 | 14 | export { 15 | isValidString 16 | }; -------------------------------------------------------------------------------- /src/utils/widget.js: -------------------------------------------------------------------------------- 1 | /* global document, window */ 2 | /* eslint-disable no-use-before-define */ 3 | 4 | /** 5 | * @param {Object} - Tawk widget required properties 6 | */ 7 | const loadScript = ({propertyId = '', widgetId = '', embedId = '', basePath = 'tawk.to', autoStart = true}) => { 8 | if (embedId.length) { 9 | /** 10 | * If the element with embedId as id we will create a new clement 11 | */ 12 | if (!document.getElementById(embedId)) { 13 | const element = document.createElement('div'); 14 | element.id = embedId; 15 | 16 | document.body.appendChild(element); 17 | } 18 | 19 | window.Tawk_API.embedded = embedId; 20 | } 21 | 22 | if (!autoStart) { 23 | window.Tawk_API.autoStart = autoStart; 24 | } 25 | 26 | const script = document.createElement('script'); 27 | script.async = true; 28 | script.src = `https://embed.${basePath}/${propertyId}/${widgetId}`; 29 | script.charset = 'UTF-8'; 30 | script.setAttribute('crossorigin', '*'); 31 | 32 | const firstScript = document.getElementsByTagName('script')[0]; 33 | firstScript.parentNode.insertBefore(script, firstScript); 34 | }; 35 | 36 | 37 | export { 38 | loadScript 39 | }; -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import { defineConfig } from 'vite' 3 | import react from '@vitejs/plugin-react' 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [react()], 8 | 9 | build : { 10 | lib : { 11 | entry : path.resolve(__dirname, 'src/index.js'), 12 | name : 'tawk-messenger-react', 13 | fileName : (format) => `tawk-messenger-react.${format}.js` 14 | }, 15 | rollupOptions : { 16 | external : ['react'], 17 | 18 | output : { 19 | globals : { 20 | react : 'React' 21 | } 22 | } 23 | } 24 | } 25 | }) 26 | --------------------------------------------------------------------------------