react-tweet
                                
                                 react-tweet copied to clipboard
                                
                                    react-tweet copied to clipboard
                            
                            
                            
                        TypeError: Cannot read properties of undefined (reading 'screen_name')
Hello I'm getting this error:
- error node_modules\react-tweet\dist\utils.js (1:63) @ screen_name
- error TypeError: Cannot read properties of undefined (reading 'screen_name')
    at stringify (<anonymous>)
and use it like this:
import { Tweet } from 'react-tweet';
const MOCKED_TWEETS = ['mock_tweet#1', 'mock_tweet#2', 'mock_tweet#3'];
export default function TwitterFeed() {
  return (
    <div className="flex flex-col w-1/5">
      {MOCKED_TWEETS.map((tweetId) => (
        <Tweet key={tweetId} id={tweetId} />
      ))}
    </div>
  );
}
any ideas?
Update to the latest version of react-tweet and try again 🙏
I just came across this issue myself as well
This was the tweet id - 1658970955203641344
It looks like fetching the tweet from X's syndication API doesn't return a valid JSON but a text/html content type. The weird part is that it works well locally but doesn't work when building in CI for prod.
@fayez-nazzal could you isolate that issue in a reproduction and share it with me? This error can happen if the twitter API does change something in their API response unexpectedly but it shouldn't be the case that it works locally and fails in CI.
I just came across this issue myself as well
This was the tweet id -
1658970955203641344
Looking at this tweet id, the api response is:
{"data":{"__typename":"TweetTombstone","tombstone":{"text":{"text":"You’re unable to view this Post because this account owner limits who can view their Posts. Learn more","entities":[{"from_index":92,"to_index":102,"ref":{"__typename":"TimelineUrl","url":"https://help.twitter.com/rules-and-policies/notices-on-twitter","url_type":"ExternalUrl"}}],"rtl":false}}}}
I haven't looked too closely at the code, but does the component validate the api response?
I came across the same issue. It's happening for me on local dev environment as well
+1
it crashes locally for me, haven't tried in prod
EDIT: One thing i've implemented is that i'm extending Tweet type with optional tombstone property and that fixed issue at least for me!
import type { VercelRequest, VercelResponse } from "@vercel/node";
import { getTweet, Tweet } from "react-tweet/api";
type ExtendedTweet =
  | (Tweet & {
      tombstone?: any;
    })
  | undefined;
const handler = async (req: VercelRequest, res: VercelResponse) => {
  const tweetId = req.query.tweet;
  if (req.method !== "GET" || typeof tweetId !== "string") {
    res.status(400).json({ error: "Bad Request." });
    return;
  }
  try {
    const tweet: ExtendedTweet = await getTweet(tweetId);
    if (tweet?.tombstone) {
      res.status(404).json({ error: "Tweet deleted", data: tweet });
      return;
    }
    res.status(tweet ? 200 : 404).json({ data: tweet ?? null });
  } catch (error: any) {
    console.error(error);
    res.status(400).json({ error: error.message ?? "Bad request." });
  }
};
export default handler;
I'm sharing piece of code that i've added in case it helps someone!
Sharing my solve for this using nextjs 14 app router:
- Have to use getTweeton serverside so wrapping it in a server apiapi/tweet/[id]/route.ts:
import { NextRequest, NextResponse } from "next/server";
import { getTweet } from "react-tweet/api";
const handler = async ( request: NextRequest, { params }: { params: { id: string } } ) => {
  try {
    const id = params?.id || (await (request.json() as any)?.id);
    if (!id) {
      return NextResponse.json({ error: 'id is required' }, { status: 400 });
    }
    const tweet = await getTweet(id);
    // useTweet requires this be inside of `data` property
    return NextResponse.json({ data: tweet ?? null }, { status: tweet ? 200 : 404});
  } catch (error: any) {
    console.log(error);
    return NextResponse.json(error.message, { status: error.statusCode || 500, statusText: error.message });
  }
}
export { handler as POST, handler as GET };
- Client side can use EmbeddedTweet,TweetNotFound,TweetSkeleton:
'use client'
import { EmbeddedTweet, TweetNotFound, TweetSkeleton, useTweet, type TweetProps } from 'react-tweet';
export const Tweet = (props: TweetProps) => {
  const { id, components, ...rest } = props;
  const { data, error, isLoading } = useTweet(id, `/api/tweet/${id}`);
  if (error) {
    const NotFound = components?.TweetNotFound || TweetNotFound;
    return <NotFound error={error} />;
  }
  if (isLoading || !data) {
    return <TweetSkeleton />;
  }
  return (
    <div className="my-6">
      <div className={`flex justify-center`}>
        <EmbeddedTweet tweet={data} components={components} {...rest} />
      </div>
    </div>
  );
};