Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Dynamically Embedding Service Desk Widget

Scott Cazan September 25, 2018

Does anyone know why when I insert the widget embed directly into the html file, it works.. but if I do it dynamicaly via JavaScript, it loads the js file but does not display the widget?

Inserting this directly into the <head> works:
<script type="text/javascript" data-jsd-embedded data-key="####" data-base-url="https://jsd-widget.atlassian.com" src="https://jsd-widget.atlassian.com/assets/embed.js"></script>

 

This does not:

const feedbackScript = document.createElement('script');

feedbackScript.type = 'text/javascript';
feedbackScript.setAttribute('data-jsd-embedded', null);
feedbackScript.setAttribute('data-key', '####');
feedbackScript.setAttribute('data-base-url', 'https://jsd-widget.atlassian.com');
feedbackScript.src='https://jsd-widget.atlassian.com/assets/embed.js';
document.head.appendChild(feedbackScript);

 

It DOES actually load the embed.js and runs (I get a response if I set an onload callback) but I see no widget.

4 answers

1 accepted

8 votes
Answer accepted
Adrian Barnes June 12, 2019

We're using Google Tag Manager and this was the solution we worked out:

<script>
function jiraHelpdesk(callback) {
var jhdScript = document.createElement('script');
jhdScript.type = 'text/javascript';
jhdScript.setAttribute('data-jsd-embedded', null);
jhdScript.setAttribute('data-key', '####');
jhdScript.setAttribute('data-base-url', 'https://jsd-widget.atlassian.com');
jhdScript.src='https://jsd-widget.atlassian.com/assets/embed.js';
if(jhdScript.readyState) { // old IE support
jhdScript.onreadystatechange = function() {
if ( jhdScript.readyState === 'loaded' || jhdScript.readyState === 'complete' ) {
jhdScript.onreadystatechange = null;
callback();
}
};
} else { //modern browsers
jhdScript.onload = function() {
callback();
};
}
document.getElementsByTagName('head')[0].appendChild(jhdScript);
}

jiraHelpdesk(function() {
var DOMContentLoaded_event = document.createEvent('Event');
DOMContentLoaded_event.initEvent('DOMContentLoaded', true, true);
window.document.dispatchEvent(DOMContentLoaded_event);
});
</script>
Deleted user March 27, 2020

Thanks a lot. It helped me as well

esha.sharma October 9, 2020

Thank you, this helped me a lot.

Deleted user January 19, 2021

This is a lifesaver. Thanks a lot!

Chris Ryan Payne August 4, 2021

Atlassian needs to put this on their main support page! Thanks!

Eben_kb October 4, 2021

Thanks for sharing. This was helpful.

Pulkit Kumar November 22, 2021

Thanks a lot! Works quite well.

Aleksandr Abramov April 11, 2023
//Thank you very much!) It helped!
//Only better to replace .initEvent with new Event


jiraHelpdesk
(function () {

  const DOMContentLoaded_event = new Event('DOMContentLoaded', {

    bubbles: true,

    cancelable: true

  );

  window.document.dispatchEvent(DOMContentLoaded_event);

});
3 votes
Pato November 5, 2018

if you read the received code, it expects an event

Run this after it has loaded

var DOMContentLoaded_event = document.createEvent("Event")
DOMContentLoaded_event.initEvent("DOMContentLoaded", true, true)
window.document.dispatchEvent(DOMContentLoaded_event)

 

this might be helpful 

https://stackoverflow.com/questions/8578617/inject-a-script-tag-with-remote-src-and-wait-for-it-to-execute

1 vote
Mees van Wel May 4, 2022

Since initEvent is deprecated it's better to use the Event constructor like this:

window.document.dispatchEvent(new Event("DOMContentLoaded", {
bubbles: true,
cancelable: true
}));
0 votes
Glenn Sampson June 21, 2022

for what is worth this is my react solution currently working for me.

Note I load the script/widget conditionally only if its internal staff 



useScript.js

 

import { useEffect } from 'react';

const useScript = (url, user) => {

  useEffect(() => {

    if (user !== null) {
      if (user.is_internal_staff) {

        const script = document.createElement('script');

        script.src = url;
        script.id = 'jiraWidget';
        script.setAttribute('async', true);
        script.setAttribute('data-jsd-embedded', '');
        script.setAttribute('data-key', "XXXXXXXX");
        script.setAttribute('data-base-url', "https://jsd-widget.atlassian.com");

        document.body.appendChild(script);

        script.addEventListener('load', (event)=>{
          window.document.dispatchEvent(new Event("DOMContentLoaded", {
            bubbles: true,
            cancelable: true
            }));
          }
        )
        return () => {
          document.body.removeChild(script);
        }
      }
    }
    else {
      // do nothing
    }
  }, [url, user]);
};

export default useScript;

Then to use it 

import useScript from '../hooks/useScript';
useScript('https://jsd-widget.atlassian.com/assets/embed.js', user); //pasing the url and the user


Khizer Rehan March 5, 2024

@Glenn Sampson I would say THANK YOU SO MUCH

I asked the question here and discussed the problem which i was able to identified it was somthing i wasn't able to LOAD widget and i tried to do another API call but resulted into CORS issue.

But i just saw your example saw

 

 

script.addEventListener('load', (event) => {
window.document.dispatchEvent(new Event('DOMContentLoaded', {
bubbles: true,
cancelable: true
}));
}
);

 

I tried my luck and GUESS what after 3hrs of struggle this worked for me. Doing this did an API call 
https://jsd-widget.atlassian.com/api/embeddable/<KEY>/widget i am not sure what trick it did but ONLY my guess is

- once DOMContent is loaded
- Event is dispatched which MAY notifies "embed.js" that DOM is loaded NOW just fetch the widget which it internally DOES api call for widget and loads in UI.


I am not sure exact explanation. But it will great to know if you have some more knowledge.


But thanks for sharing example

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events