Skip to Content

Advanced

Customizing the theme components

The components used by the Twitter theme allow some simple customization options for common use cases. However you can also have full control over the tweet by building your own Tweet component with the components and features of the theme that you would like to use.

For example, you can build your own tweet component but without the reply button like so:

my-tweet.tsx
import type { Tweet } from 'react-tweet/api' import { type TwitterComponents, TweetContainer, TweetHeader, TweetInReplyTo, TweetBody, TweetMedia, TweetInfo, TweetActions, QuotedTweet, enrichTweet, } from 'react-tweet' type Props = { tweet: Tweet components?: TwitterComponents } export const MyTweet = ({ tweet: t, components }: Props) => { const tweet = enrichTweet(t) return ( <TweetContainer> <TweetHeader tweet={tweet} components={components} /> {tweet.in_reply_to_status_id_str && <TweetInReplyTo tweet={tweet} />} <TweetBody tweet={tweet} /> {tweet.mediaDetails?.length ? ( <TweetMedia tweet={tweet} components={components} /> ) : null} {tweet.quoted_tweet && <QuotedTweet tweet={tweet.quoted_tweet} />} <TweetInfo tweet={tweet} /> <TweetActions tweet={tweet} /> {/* We're not including the `TweetReplies` component that adds the reply button */} </TweetContainer> ) }

Then, you can build your own Tweet component that uses the MyTweet component:

tweet.tsx
import { Suspense } from 'react' import { getTweet } from 'react-tweet/api' import { type TweetProps, TweetNotFound, TweetSkeleton } from 'react-tweet' import { MyTweet } from './my-tweet' const TweetContent = async ({ id, components, onError }: TweetProps) => { const tweet = id ? await getTweet(id).catch((err) => { if (onError) { onError(err) } else { console.error(err) } }) : undefined if (!tweet) { const NotFound = components?.TweetNotFound || TweetNotFound return <NotFound /> } return <MyTweet tweet={tweet} components={components} /> } export const Tweet = ({ fallback = <TweetSkeleton />, ...props }: TweetProps) => ( <Suspense fallback={fallback}> {/* @ts-ignore: Async components are valid in the app directory */} <TweetContent {...props} /> </Suspense> )

The Tweet component uses Suspense to progressively load the tweet (non-blocking rendering) and to opt-in into streaming if your framework supports it, like Next.js.

TweetContent is an async component that fetches the tweet and passes it to MyTweet. async only works for React Server Components (RSC)  so if your framework does not support RSC you can use SWR  instead:

tweet.tsx
'use client' import { type TweetProps, EmbeddedTweet, TweetNotFound, TweetSkeleton, useTweet, } from 'react-tweet' export const Tweet = ({ id, apiUrl, fallback = <TweetSkeleton />, components, onError, }: TweetProps) => { const { data, error, isLoading } = useTweet(id, apiUrl) if (isLoading) return fallback if (error || !data) { const NotFound = components?.TweetNotFound || TweetNotFound return <NotFound error={onError ? onError(error) : error} /> } return <EmbeddedTweet tweet={data} components={components} /> }
Last updated on