Embedded and static tweets for Next.js applications
react-tweet
Embedded and static tweet for Next.js applications.
Installation
Next.js 13.2.1 or higher is required in order to use
react-tweet
.
Install react-tweet
using your package manager of choice:
pnpm add react-tweet
yarn add react-tweet
npm install react-tweet
Currently, react-tweet
uses next/image
behind the scenes. You can configure next/image
to accept image URLs from Twitter, by using images.remotePatterns
in next.config.js
:
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{ protocol: 'https', hostname: 'pbs.twimg.com' },
{ protocol: 'https', hostname: 'abs.twimg.com' },
],
},
}
Now follow the usage instructions below. No API keys are required.
Usage with App Router
In any component, import NextTweet
from react-tweet
and use it like so:
import { NextTweet } from 'react-tweet'
export default function Page({ params }: Props) {
return <NextTweet id={params.tweet} />
}
NextTweet
accepts the following props:
id
–string
: the tweet ID. For example inhttps://twitter.com/chibicode/status/1629307668568633344
the tweet ID is1629307668568633344
.notFoundOnError
–boolean
: iftrue
, the component will show a not found message if the tweet fails to load (invalid id, no longer exists, account went private, etc). Otherwise, it will throw an error. Defaults tofalse
.
NextTweet
takes care of fetching the tweet and rendering it. You can see it working in the Next.js sample app that’s part of this monorepo.
Choosing a theme
The prefers-color-scheme
CSS media feature is used to select the theme of the tweet.
Toggling theme manually
The closest data-theme
attribute on a parent element can determine the theme of the tweet. You can set it to light
or dark
, like so:
<div data-theme="dark">
<NextTweet id={params.tweet} />
</div>
Alternatively, a parent with the class light
or dark
will also work:
<div className="dark">
<NextTweet id={params.tweet} />
</div>
Usage in pages directory
Use the getTweet
function from react-tweet
to fetch the tweet and send it as props to the page component:
import { getTweet, type Tweet } from 'react-tweet/api'
export async function getStaticProps({
params,
}: {
params: { tweet: string }
}) {
try {
const tweet = await getTweet(params.tweet)
return tweet ? { props: { tweet } } : { notFound: true }
} catch (error) {
return { notFound: true }
}
}
export async function getStaticPaths() {
return { paths: [], fallback: true }
}
export default function Page({ tweet }: { tweet: Tweet }) {
return <TweetPage tweet={tweet} />
}
The TweetPage
component uses EmbeddedTweet
to render the tweet, and TweetSkeleton
to render a skeleton in case you need a loading state (e.g. when using fallback: true
in getStaticPaths
):
import { useRouter } from 'next/router'
import { EmbeddedTweet, TweetSkeleton } from 'react-tweet'
import type { Tweet } from 'react-tweet/api'
const TweetPage = ({ tweet }: { tweet: Tweet }) => {
const { isFallback } = useRouter()
return (
<div data-theme="dark">
{isFallback ? <TweetSkeleton /> : <EmbeddedTweet tweet={tweet} />}
</div>
)
}
export default TweetPage
You can see it working in the test app that’s part of this monorepo.
Running the test app
Clone this repository and run the following command:
pnpm install && pnpm dev
Now visit http://localhost:3000/light/1629307668568633344 to see the tweet in the app directory, and http://localhost:3000/dark/1629307668568633344 to see the tweet in the pages directory.
The test app uses the react-tweet
package in the root directory, so you can make changes to the package and see the changes reflected in the test app immediately.