FacebookFeed

A React Facebook UI component - the news feed post, the reel and the story. For clones, mockups and references.

FacebookFeed playground

The caption sits above the media - the opposite of Instagram. A still is echoed into the blurred letterbox; a clip letterboxes to flat black.

Install FacebookFeed

1. New project? One command installs the package and wires everything - see Installation:

bash
pnpm dlx zyncat-ui init

2. Import the component - it loads its own stylesheet:

tsx
import { FacebookFeed } from '@zyncat/ui/facebook-feed';

Usage

tsx
import { FacebookFeed } from '@zyncat/ui/facebook-feed';
 
<FacebookFeed surface="post" name="Zyncat Studio" caption="New build is live." media={photo} likes={1240} />

Compose FacebookFeed in your application. No Tailwind or external styling library is required; every value resolves from Zyncat UI's token vocabulary.

FacebookFeed props

FacebookFeed

PropTypeDefaultDescription
...htmlAttributesHTMLAttributes—Standard element attributes (aria-*, data-*, title, ...) forwarded to the surface root.
surfaceFacebookSurface'post'Which Facebook surface to reproduce: the feed card, the reels stage, or the story stage.
widthFacebookPostWidth'web'Feed card width. `mobile` is the 390px square-cornered card, `web` the 680px rounded one.
stageFacebookReelStage'narrow'Reels stage. `narrow` is 557x878 around a 9:16 video, `wide` is 1601x886 around a 16:9 one.
typeFacebookMediaType'image'Whether `media` is a still or a clip. A still is echoed into the feed's blurred letterbox backdrop; a clip is not, so it is never fetched twice.
namestring'Swiss Nature'Poster or page name in the header.
captionstring—Post body. The feed cuts it at 250 characters with `See more`; reels take one ellipsised line. Hashtags and
ratioFacebookRatio'4:5'Frame aspect for the feed card and the story card. Reels stages are fixed.
mediaReactNode—A URL string, or your own node (`<img>`, `<video>`, `next/image`). Omit for a CSS-only placeholder. Nothing is ever autoplayed and no request is ever made for you.
avatarReactNode—A URL string, or your own node, for the header portrait. Omit for the platform's grey.
followbooleantrueShow the `· Follow` affordance. Blue in the feed, white on reels.
ringbooleantrueBlue active-story ring around the feed avatar.
stampstring'31m'Relative timestamp in the meta line.
verifiedbooleantrueBlue verified badge after the reels name.
audiostring'Original audio'Track name on the reels and story audio line.
likesnumber267Reaction count. Exact below 1,000, then `1.2K` / `48K` / `1.4M`.
commentsnumber12Comment count, formatted like `likes`.
sharesnumber4Share count, formatted like `likes`.
segmentsnumber2How many story progress segments to draw.
segmentnumber0Index of the newest filled story segment; every earlier one fills too.
mutedboolean—Controlled mute state for the reels and story sound button.
defaultMutedbooleantrue on reels, false on the storyUncontrolled initial mute state.
onMutedChange(muted: boolean) => void—Fires when the sound button is pressed. You own the actual `<video>`, so wire it to your own element.
likedboolean—Controlled like state for the thumb on the feed card and the reels rail. The displayed reaction count adds one while this is on.
defaultLikedbooleanfalseUncontrolled initial like state.
onLikedChange(liked: boolean) => void—Fires when the thumb toggles the like.
onAction(action: FacebookFeedAction) => void—Fires for the actions that carry no state: comment, share, follow, menu, dismiss, more, search, play.
classNamestring—Extra class(es) merged onto the surface root.
styleCSSProperties—Inline styles merged onto the surface root.

Frequently asked questions

Import the component and pick a surface: <FacebookFeed surface="post" width="web" name="Alpenglow Daily" caption="Three days above the fog line" media={photo} likes={12400} />. surface takes post, reel or story, width takes mobile (the 390px square-cornered card) or web (the 680px rounded one), and ratio frames the media at 4:5, 1.1:1, 1:1, 3:4 or 16:9. It is the Facebook UI only, so you keep your own data layer and your own backend.

No. There is no Facebook API, no Graph API call, no login and no real posts - it replicates how the news feed looks and behaves, and nothing more. Every value on screen is a prop you pass: name, caption, stamp, avatar, media, likes, comments and shares, with counts rendered exact below 1,000 and then compacted to 1.2K, 48K or 1.4M the way Facebook does.

Three, behind one surface prop. post is the news feed card - caption above the media the way Facebook does it, the blurred saturated letterbox behind the frame, the like, comment and share bar, and the like/love reaction pips. reel is the reels stage at 557x878 around a 9:16 clip or 1601x886 around a 16:9 one, and story is a 486x864 stage with the segmented progress track that segments and segment drive.

Yes - a mockup is what a replica is for. It draws a live Facebook post card in the DOM at the platform's real metrics, so it stays sharp at any zoom and never ages out of date the way a PSD, a Figma frame or an old screenshot does. It is a React component rather than a fake-post image generator: nothing is submitted anywhere, and the content is whatever you pass in props.

Two toggles and one report. liked toggles the thumb on the feed card and the reels rail and adds one to the displayed reaction count, muted toggles the speaker on reels and stories, and both are controllable through liked/defaultLiked/onLikedChange and muted/defaultMuted/onMutedChange. Everything else is stateless and reports through onAction: comment, share, follow, menu, dismiss, more, search and play, each fired by a real button carrying an aria-label.

Yes. @zyncat/ui/facebook-feed ships compiled ESM with its 'use client' directive intact, so it drops into the Next.js App Router with no transpilePackages config and zero runtime dependencies. media and avatar take a URL string or your own node, so next/image, a plain <img> or a <video> all work - nothing autoplays and no request is made for you. Being a replica, its metrics are pinned constants your theme cannot move; only the type reads --font-body.

Set in Geist & Newsreader — animated by the house engineZyncat UI · Rev 0.11 · MIT · Built by Tabsir Ahammed · Source on GitHub