abrahamlinkedin
abrahamlinkedin

Reputation: 467

How to embed Twitter widget to Reactjs?

Going to the twitter widget site (https://publish.twitter.com/) I am able to get a widget to add to my site. I am using the sample code to try to understand hot it works:

<a class="twitter-grid" href="https://twitter.com/TwitterDev/timelines/539487832448843776">National Park Tweets</a> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

If I just add this to an HTML page then the code works exactly as it should. It shows the grid with the respective tweets.

However, when adding this to ReactJS all I see is the fallback code, which merely provides a link to the twitter username.

I have tried using the following to no avail:

  <div dangerouslySetInnerHTML={{__html: "<a className='twitter-grid' href='https://twitter.com/TwitterDev/timelines/539487832448843776'>National Park Tweets</a> <script async src='https://platform.twitter.com/widgets.js' charset='utf-8'></script>"}}>
  </div>

Upvotes: 6

Views: 14574

Answers (3)

Andy
Andy

Reputation: 73

I was having issues with the twttr.widgets.load() method displaying the Tweet text before adding the styling. This is how I solved that with the twttr.widgets.createTweet() method and adding a loading state.

(Also using TypeScript & Tailwind CSS - feel free to remove that as needed.)

Add script to inside body in index.html:

<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>
  <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 
</body>

Create Tweet component:

import { useEffect, useState } from "react";

export default function Tweet({
  tweetID,
}: TweetProps) {
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    if ((window as any).twttr) {
      (window as any).twttr.widgets.createTweet(
        tweetID,
        document.getElementById(tweetID),
        {
          align: 'center',
          conversation: 'none',
          dnt: true,
          theme: 'dark',
        }
      ).then(() => setIsLoading(false));
    };
  }, [tweetID]);

  return (
    <div className="w-full animate-fadeIn" id={tweetID}>
      {isLoading && <p>LOADING</p>}
    </div>
  );
};

interface TweetProps {
  tweetID: string,
};

// twttr.widgets.createTweet:
// https://developer.twitter.com/en/docs/twitter-for-websites/embedded-tweets/guides/embedded-tweet-javascript-factory-function

// Embedded Tweet parameter reference
// https://developer.twitter.com/en/docs/twitter-for-websites/embedded-tweets/guides/embedded-tweet-parameter-reference

Usage:

  <Tweet tweetID="1002103497725173760" />

Upvotes: 2

dahliacreative
dahliacreative

Reputation: 441

I don't know if other people are still having this problem, but in my situation I was getting article body content from an API and simply inserting that html into a div and couldn't get the tweets to work properly.

Just figured out a solution though, so I have the widgets js in my index.html.

Then on component update I check that my article content has loaded then simply call twttr.widgets.load()

Here is my componentDidUpdate function:

componentDidUpdate(props) {
      if(this.props.article.status === 'FULFILLED' && this.props.article.status !== props.article.status) {
        twttr.widgets.load(
          document.getElementById('article')
        )
      }
    }

Hope someone else finds this useful!

Upvotes: 3

BradByte
BradByte

Reputation: 11093

Check out this npm package: react-twitter-widgets. This seems to be accomplishing what you need out of box.

import { Tweet } from 'react-twitter-widgets'

ReactDOM.render(<Tweet tweetId='511181794914627584'/>, document.getElementById('root'))

Upvotes: 9

Related Questions