Discussion
Threaded discussion / commenting component. Two-level threading (top-level posts and replies), four sort modes, cursor-based pagination, reactions, post reporting, and authentication-aware UI.
Import
import { Discussion } from "fansunited-frontend-components";
import { DiscussionProps, DiscussionSortType } from "fansunited-frontend-core";Required props
| Prop | Type | Description |
|---|---|---|
entityId | string | Unique discussion identifier (e.g. article ID, match ID). |
sdk | FansUnitedSDKModel | SDK instance. |
language | LanguageType | Display language. |
Discussiondoes not take atemplateprop — its layout is always a single threaded list that adapts to the container width.
Optional props
| Prop | Type | Default | Description |
|---|---|---|---|
themeOptions | CustomThemeOptions | — | See Theming. |
discussionLabel | string | — | Title used when the discussion is created for the first time. |
discussionUrl | string | — | URL associated with the discussion content (used in shares/back-references). |
defaultSort | DiscussionSortType | "LATEST" | Initial sort order. |
postsPerPage | number | 20 | Posts loaded per page. |
showReactions | boolean | true | Show reaction buttons. |
showReplies | boolean | true | Enable reply functionality. |
showReportPost | boolean | true | Show the report option in the post menu. |
showModeratedPosts | boolean | false | Display moderated posts with a masked design (content replaced by the moderation reason). |
infiniteScroll | boolean | false | Load more posts on scroll instead of showing a "Load More" button. |
userIsLoggedIn | boolean | false | Whether the current user is authenticated. |
onSignInClick | () => void | — | Callback when the sign-in prompt is clicked. |
Note:
Discussionuses a simpleronSignInClickcallback, not the fullSignInCTADetailsobject.
Sort modes
type DiscussionSortType = "LATEST" | "OLDEST" | "POPULAR" | "INTERACTED";| Value | Order |
|---|---|
LATEST | Newest first (default). |
OLDEST | Oldest first. |
POPULAR | Most-reacted first. |
INTERACTED | Most-replied first. |
Authentication and sign-in
When userIsLoggedIn={false}:
- The post composer is replaced with a sign-in prompt.
- Reactions, replies, delete, and report actions are gated behind authentication.
- Passing
onSignInClickmakes the sign-in button active; omitting it shows a disabled button.
<Discussion
{...otherProps}
userIsLoggedIn={false}
onSignInClick={() => openSignInModal()}
/>Reactions
Eight reaction types are available when showReactions={true}:
type ReactionType = "LIKE" | "DISLIKE" | "LOVE" | "LAUGH" | "CARE" | "WOW" | "SAD" | "ANGRY";- Click an emoji to toggle the reaction.
- Click the same emoji again to remove it.
- Only authenticated users can react.
Moderated posts
showModeratedPosts={true} fetches and displays moderated comments with a masked design. The original content is replaced by the moderation reason (or a localised fallback), while avatar, username, timestamp, reactions, and reply button remain visible.
Examples
Basic
<Discussion
entityId="article-123"
sdk={sdk}
language="en"
discussionLabel="Liverpool vs Man City — Match Reaction"
/>Authenticated user, full features
<Discussion
entityId="article-123"
sdk={sdk}
language="en"
discussionLabel="Liverpool vs Man City — Match Reaction"
discussionUrl="https://your-site.com/articles/liverpool-vs-man-city"
userIsLoggedIn={true}
defaultSort="POPULAR"
postsPerPage={10}
showReactions
showReplies
showReportPost
themeOptions={{ mode: "light" }}
/>Minimal read-only style
<Discussion
entityId="article-123"
sdk={sdk}
language="en"
discussionLabel="Post Comments"
userIsLoggedIn={false}
showReactions={false}
showReplies={false}
showReportPost={false}
onSignInClick={() => openSignInModal()}
/>Dark theme with sign-in integration
<Discussion
entityId="match-456"
sdk={sdk}
language="en"
discussionLabel="Match Day Chat"
userIsLoggedIn={isUserLoggedIn}
onSignInClick={() => router.push("/login")}
defaultSort="LATEST"
postsPerPage={20}
themeOptions={{
mode: "dark",
colorSchemes: {
dark: {
surface: "#212121",
textPrimary: "#FAFAFA",
palette: {
primary: {
plainColor: "#2397F3",
primaryContainer: "#1A77D2",
onPrimary: "#FFFFFF",
},
},
},
},
}}
/>