Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/transitive-bullshit/react-static-tweets
Extremely fast static renderer for tweets.
https://github.com/transitive-bullshit/react-static-tweets
nextjs react ssr tweet tweets twitter
Last synced: 5 days ago
JSON representation
Extremely fast static renderer for tweets.
- Host: GitHub
- URL: https://github.com/transitive-bullshit/react-static-tweets
- Owner: transitive-bullshit
- License: mit
- Archived: true
- Created: 2021-02-15T03:15:18.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2024-04-24T05:33:03.000Z (6 months ago)
- Last Synced: 2024-05-02T00:53:50.355Z (6 months ago)
- Topics: nextjs, react, ssr, tweet, tweets, twitter
- Language: TypeScript
- Homepage: https://react-tweet.vercel.app
- Size: 891 KB
- Stars: 565
- Watchers: 5
- Forks: 46
- Open Issues: 18
-
Metadata Files:
- Readme: readme.md
- Funding: .github/funding.yml
- License: license
Awesome Lists containing this project
- awesome-list - react-static-tweets - bullshit | 354 | (TypeScript)
README
# Deprecation Notice
Vercel released [react-tweet](https://github.com/vercel/react-tweet) which is a better maintained version of this library. Please use that instead.
---
# React Static Tweets
> Extremely fast static renderer for tweets.
[![NPM](https://img.shields.io/npm/v/react-static-tweets.svg)](https://www.npmjs.com/package/react-static-tweets) [![Build Status](https://github.com/transitive-bullshit/react-static-tweets/actions/workflows/test.yml/badge.svg)](https://github.com/transitive-bullshit/react-static-tweets/actions/workflows/test.yml) [![Prettier Code Formatting](https://img.shields.io/badge/code_style-prettier-brightgreen.svg)](https://prettier.io)
## Demo
Visit [react-static-tweets.vercel.app](https://react-static-tweets.vercel.app/1352687755621351425) and append your tweet ID. You can also append `/dynamic/` if you want to test the non-SSR version.
## Why?
Twitter's embedding SDK is horribly slow and inefficient. For embedding tweets on your site (including SSR), this solution is significantly more performant. 🔥
This project takes Vercel's work on [static tweet rendering](https://static-tweet.vercel.app) and packages it up into two easy-to-use NPM packages.
## Features
- âš¡ **Fast** - 10-100x faster than using Twitter's iframe embedding.
- 🔥 **Solid** - Used in production by [super.so](https://s.super.so/x), [react-notion-x](https://transitivebullsh.it/nextjs-notion-starter-kit), and others.
- 🚀 **Simple** - TypeScript + React.## Install
```bash
npm install react-static-tweets static-tweets date-fns
# or
yarn add react-static-tweets static-tweets date-fns
```Note: this project currently only works with **Next.js** (see [#2](https://github.com/transitive-bullshit/react-static-tweets/issues/2) for more info).
## Usage
You'll need to pre-fetch tweet data server-side using `fetchTweetAst` and then render it using the `Tweet` component.
```tsx
import React from 'react'
import { fetchTweetAst } from 'static-tweets'
import { Tweet } from 'react-static-tweets'const tweetId = '1358199505280262150'
export const getStaticProps = async () => {
try {
const tweetAst = await fetchTweetAst(tweetId)return {
props: {
tweetAst
},
revalidate: 10
}
} catch (err) {
console.error('error fetching tweet', err)throw err
}
}export default function Example({ tweetAst }) {
return
}
```Note that `Tweet` is a React server component, and has been tested with Next.js 13 `appDir`.
## Advanced Usage
If you have multiple tweets and are okay with using client components, then we recommend using the built-in `TwitterContextProvider` to store a map from tweet ID to tweet AST.
In this example, we're using the client component imports from `react-static/tweets/client` which use React Context under the hood:
```tsx
import React from 'react'
import pMap from 'p-map'
import { fetchTweetAst } from 'static-tweets'
import { TweetClient, TwitterContextProvider } from 'react-static-tweets/client'// NOTE: You'll likely infer your list of tweets by introspecting your page's
// content from a CMS.
const tweetIds = [
'1358199505280262150',
'1374492662061953034',
'1358199505280262150'
// ...
]export const getStaticProps = async () => {
try {
// Fetch all tweet ASTs statically
const tweetAsts = await pMap(tweetIds, fetchTweetAst, {
concurrency: 4
})// Create a map from tweet ID to tweet AST
const tweetAstMap = tweetIds.reduce((tweetId, map, index) => ({
...map,
[tweetId]: tweetAsts[index]
}))return {
props: {
tweetAstMap
},
revalidate: 60
}
} catch (err) {
console.error('error fetching tweets', err)throw err
}
}export default function Example({ tweetAstMap }) {
return (
{tweetIds.map((tweetId) => (
{/*
There's no need to pass the tweet AST directly if it is provided via TwitterContextProvider. This is nice in situations where you're
rendering tweets in deeply nested component trees.
*/}
))}
)
}
```## Styles
You'll need to import some CSS styles as well. For Next.js, we recommend you put these in `pages/_app`:
```ts
import 'react-static-tweets/styles.css'
```## Next.js Config
Add `pbs.twimg.com` to your `next.config.js` since we use `next/image` to load images.
```js
module.exports = {
images: {
domains: ['pbs.twimg.com']
}
}
```## Next.js Example
Here is an [example Next.js project](./example), with the most important code in [`pages/[tweetId].tsx`](./example/pages/%5BtweetId%5D.tsx). You can view this example [live on Vercel](https://react-static-tweets.vercel.app).
## Packages
| Package | NPM | Environment | Description |
| ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ------------- | --------------------------------------- |
| [static-tweets](./packages/static-tweets) | [![NPM](https://img.shields.io/npm/v/static-tweets.svg)](https://www.npmjs.com/package/static-tweets) | Node.js | Fetches tweet ASTs. |
| [react-static-tweets](./packages/react-static-tweets) | [![NPM](https://img.shields.io/npm/v/react-static-tweets.svg)](https://www.npmjs.com/package/react-static-tweets) | Browser + SSR | React renderer for tweets given an AST. |## Dynamic Client-Side Rendering
`react-static-tweets` is meant for rendering tweets as efficiently as possible. The `Tweet` component assumes that you've already pre-fetched tweet AST data ahead of time, most likely during SSR.
Rendering dynamic tweets on the client-side is supported; however, you'll need to wrap `fetchTweetAst` in an API route since it can't be used from the browser.
You can view an example of this in action via [`example/pages/dynamic/[tweetId].tsx`](./example/pages/dynamic/%5BtweetId%5D.tsx).
## Credit
My main contribution is packaging the Vercel team's excellent work into two isolated packages: `static-tweets` for server-side fetching of tweet ASTs and `react-static-tweets` for client-side rendering as well as SSR.
- Inspired by this [demo](https://static-tweet.vercel.app/) from the Vercel team
- And the underlying [repo](https://github.com/lfades/static-tweet) by [Luis Alvarez](https://github.com/lfades)
- Most of the core code is adapted from [Guillermo Rauch's blog](https://github.com/rauchg/blog/blob/master/pages/2020/2019-in-review.js)
- Converted the JS codebase to TypeScript
- Removed `styled-jsx` because using a flat CSS file (with a `.static-tweet` class prefix) makes bundling for NPM easier
- Fixed some minor formatting bugs## License
MIT © [Travis Fischer](https://transitivebullsh.it)
Support my OSS work by following me on twitter