Search code examples
javascripttwitterembed

How can I resolve this Twitter JS embed factory error?


I have been trying to embed a list of Tweets on a webpage but it produces this error. I believe I've followed the docs properly, for both the JS factory function and widget.js.

I haven't been able to find a similar issue elsewhere and Twitter doesn't seem to provide any documentation for this type of issue.

This is the part of the website that is supposed to generate the embeds:

<div id="tweet-container"></div>
<div>
  <script type="text/javascript" src="widgets.js"></script>
  <script type="text/javascript" src="organise.js"></script>
  <script type="text/javascript">
    organise({{ tweets | tojson }});
  </script>
</div>

organise.js:

function organise(tweetList){

  for (let i = 0; i < tweetList.length; i++) {

    var newDiv = document.createElement('div')
    newDiv.innerHTML = '<div id="video-${i}"'

    document.getElementById("tweet-container").appendChild(newDiv)

    twttr.widgets.createTweet(
      tweetList[i]["url"],
      document.getElementById(`video-${i}`),
      omit_script=true,
      {
        conversation: 'none',
        align: 'center',
        theme: 'dark'
        }
      )
      .then( function( el ) {
        console.log('Tweet added.');
    });
  }
}

And widgets.js:

window.twttr = (function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0],
    t = window.twttr || {};
  if (d.getElementById(id)) return t;
  js = d.createElement(s);
  js.id = id;
  js.src = "https://platform.twitter.com/widgets.js";
  fjs.parentNode.insertBefore(js, fjs);

  t._e = [];
  t.ready = function(f) {
    t._e.push(f);
  };

  return t;
}(document, "script", "twitter-wjs"));

Then this is the error I receive: Error on the webpage.


Solution

  • I have no idea if this is documented anywhere. I couldn't find anything in the twitter guides that mention this.

    The problem is that twttr.widgets is undefined (which I'm sure you realized) which seemed odd to me because it tells me that twttr is not undefined. So I wanted to see what twttr was and console logged it.

    I noticed the object has a ready method on it that takes a callback so I tried this:

    function organise(tweetList){
        twttr.ready(() => {
            console.log(twttr.widgets)
        })
    
    // ..
    

    And now widgets is defined!

    enter image description here

    So you'll need to wrap the code inside of your organise function within a callback that you give to twttr.ready.

    Might look like this for example:

    function organise(tweetList){
        twttr.ready(() => {
            for (let i = 0; i < tweetList.length; i++) {
          
              var newDiv = document.createElement('div')
              newDiv.innerHTML = '<div id="video-${i}"'
          
              document.getElementById("tweet-container").appendChild(newDiv)
        
          
              twttr.widgets.createTweet(
                tweetList[i]["url"],
                document.getElementById(`video-${i}`),
                omit_script=true,
                {
                  conversation: 'none',
                  align: 'center',
                  theme: 'dark'
                  }
                )
                .then( function( el ) {
                  console.log('Tweet added.');
              });
            }
        })
      }