Skip to content

Instantly share code, notes, and snippets.

@GendelfLugansk
Created August 3, 2019 18:48
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save GendelfLugansk/d3e85bcfa13088ab6bd20058f3e73db8 to your computer and use it in GitHub Desktop.
Save GendelfLugansk/d3e85bcfa13088ab6bd20058f3e73db8 to your computer and use it in GitHub Desktop.
Dynamically change tawk locale

If you need to change tawk's locale dynamically (i.e. in SPA), here is the code I use. There is a small issue, though - everytime tawk adds new div to body and there is no way to correctly detect it and remove (ids are dynamic and there is no classname). However, as far as it is hidden, this should not be a problem.

function _setupTawk(locale) {
/**
* Links for language-specific channels or projects, you can find them in original tawk embed code
*/
const localeToLink = {
ru: 'https://embed.tawk.to/secret/secret',
en: 'https://embed.tawk.to/secret/secret',
};
/**
* Hide widget if tawk is loaded
*/
if (
window.Tawk_API !== undefined &&
typeof window.Tawk_API.hideWidget === 'function'
) {
window.Tawk_API.hideWidget();
}
/**
* Delete script tags of tawk
*/
const scripts = document.getElementsByTagName('script');
for (let i = 0; i < scripts.length; i++) {
const tag = scripts[i];
if (tag.getAttribute('tawk') === 'yes') {
tag.parentNode.removeChild(tag);
}
}
/**
* Delete anything related to tawk, otherwise new widget would not be loaded
*/
for (const name in window) {
if (
window.hasOwnProperty(name) &&
(name.includes('tawk') || name.includes('Tawk'))
) {
delete window[name];
}
}
/**
* Almost the same code as original
*/
window.Tawk_API = {};
window.Tawk_LoadStart = new Date();
(function() {
const s1 = document.createElement('script'),
s0 = document.getElementsByTagName('script')[0];
s1.async = true;
s1.src = localeToLink[locale]; //Here we use correct url for locale
s1.charset = 'UTF-8';
s1.setAttribute('crossorigin', '*');
s1.setAttribute('tawk', 'yes'); //This line is used to mark tawk script
s0.parentNode.insertBefore(s1, s0);
})();
}
@betoflakes
Copy link

Have you used this code recently?
I'm facing a sessionHandler or viewHandler error when hideWidget or any Tawk API services.

Cannot read property 'viewHandler' of null at Object.u.hideWidget.Tawk_API.hideWidget

@GendelfLugansk
Copy link
Author

Have you used this code recently?
I'm facing a sessionHandler or viewHandler error when hideWidget or any Tawk API services.

Cannot read property 'viewHandler' of null at Object.u.hideWidget.Tawk_API.hideWidget

Yes, I have a web app that contains this code and it works just fine for me. You can try to visit https://app.tradary.com/ from PC (tawk there is disabled on mobile), switch language and see if it changes tawk widget.

@sathlerhe
Copy link

I'm getting the error TypeError: Cannot delete property 'Tawk_API' of #<Window>

@Rehum02
Copy link

Rehum02 commented Nov 15, 2021

How i proceed to use TawkTO In My Angular app ?

1 - In index.html head part, i import Tawk_To

  <script type="text/javascript">var Tawk_API=Tawk_API||{}, Tawk_LoadStart=new Date();(function(){var s1=document.createElement("script"),s0=document.getElementsByTagName("script")[0];s1.async=true;s1.src='https://embed.tawk.to/xxxxxx'; s1.charset='UTF-8';s1.setAttribute('crossorigin','*');s0.parentNode.insertBefore(s1,s0);})();</script>
  <script> var TAWK_TO_LOAD = 0; </script> // That variable helps to know if TawkTo already loaded

2 - In ProductGlobalFunctComponent. I call that component everywhere. Its contains some globals functions


declare var Tawk_API:any;
declare var TAWK_TO_LOAD:any;

/**@f_TAWKTO_manage Hide / Show TackTo With */
  f_TAWKTO_manage(){
    if(!Tawk_API){ console.log('Window TawkTo API NOT_EXIST  ...'); return; }
 
    var this_ = this; 
    if(!TAWK_TO_LOAD)
    {
      Tawk_API.onLoad =  function(){ TAWK_TO_LOAD++; this_.f_TAWKTO_showhide();  };
    } else {
      this_.f_TAWKTO_showhide();
    }
  }
  /**@f_TAWKTO_showhide Show Hide Widget  */
  f_TAWKTO_showhide(){
    var hidden_on_pages = ['account/liveroom', 'account/b'];  // This Variable contains components where i would like to hide TAWK TO Widget 

   // Get Component Path
    var p = location.pathname.slice(1);  
    var p_arr = p.split('/');
    if( p_arr.length >=3 ){   p = (p_arr[0] +'/' + p_arr[1]);} 
    else if(p_arr.length  <= 2){    p = p_arr[0];   } 

    if(hidden_on_pages.indexOf(p) != -1)  
    {
      console.log('Hidding TAWK_TO  ...');
      Tawk_API.hideWidget();      // window.Tawk_API.hideWidget();    // (window as any).Tawk_API.hideWidget();
      return;
    }
    console.log('Showing TAWK_TO  ...');
    Tawk_API.showWidget();        // (window as any).Tawk_API.showWidget();
  }


3- I call ProductGlobalFunctComponent in the component i want to use.

...
constructor(private productglobalfunc ProductGlobalFunctComponent ){}

ngAfterContentInit()
{
  this.productglobalfunc .f_TAWKTO_manage()
}
...


May it helps someone

@MR-POSITIVE
Copy link

I'm getting the error TypeError: Cannot delete property 'Tawk_API' of #<Window>

Did anyone face this similar challenge.. as its reproducible. In my scenario i want to load different chat form for different router.

@GendelfLugansk
Copy link
Author

@MR-POSITIVE any further detais? Traces? Because my installation still works fine

@javimrtnez
Copy link

javimrtnez commented Dec 22, 2022

@GendelfLugansk I've noticed that if you change the language and then maximize and minimize the chat you will see it in a different language for a moment, so, this piece of code could be useful to remove by his CSS class the divs added to body and solve the problem commented in README.md?

However, it could be dangerous because there could be classes created by us with widget-visible names.

Array.from(document.getElementsByClassName('widget-visible')).forEach(
  (widgetVisibleElement) => {
    widgetVisibleElement.remove();
  }
);

PD: I've also changed the function to minimize the widget because hidding it wasn't working propertly for me:

if (window.Tawk_API) {
  window.Tawk_API.minimize();
}

@Mihai-github
Copy link

It would be helpful to have the ability to adjust the size of the widget or customize it in other ways. This is particularly important on mobile devices, where the widget bubble can obscure crucial elements like buttons and links.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment