Skip to main content

Threaded Comments Props

The ThreadedCommentSection component follows a minimal props philosophy. It works with just entityId and offers optional props for specific needs.

Component Import

import { ThreadedCommentSection } from './components/comments-threaded';

Props Interface

interface ThreadedCommentSectionProps {
  // Entity identification (provide ONE of these)
  entity?: Entity | undefined | null;
  entityId?: string | undefined | null;
  foreignId?: string | undefined | null;
  shortId?: string | undefined | null;

  // Optional features
  isVisible?: boolean;
  highlightedCommentId?: string | undefined | null;
  theme?: 'light' | 'dark';                    // Only for styled variant
  children?: React.ReactNode;
}

Entity Identification

One of these is required to identify which entity (post, article, etc.) the comments belong to:

entity

Type: Entity | undefined | null A complete Entity object.
<ThreadedCommentSection
  entity={{
    id: "entity_123",
    projectId: "proj_456",
    foreignId: "post-789",
    // ... other entity fields
  }}
/>
Use when: You already have the full entity object from useFetchEntity or similar hooks.

entityId

Type: string | undefined | null The internal Replyke ID for the entity.
<ThreadedCommentSection
  entityId="entity_123"
/>
Use when: You know the Replyke entity ID.

foreignId

Type: string | undefined | null Your external/custom ID for the entity.
<ThreadedCommentSection
  foreignId="blog-post-789"
/>
Use when: You’re using your own IDs and haven’t fetched the Replyke entity yet.

shortId

Type: string | undefined | null A short, human-readable identifier (if you’ve set one).
<ThreadedCommentSection
  shortId="my-first-post"
/>
Use when: You’ve created entities with custom short IDs for URLs.
You only need ONE of these props. They’re mutually compatible — use whichever fits your data model best.

Optional Props

isVisible

Type: boolean Default: true Controls whether the comment section is visible. Useful when rendering inside a drawer, modal, or conditional layout.
const [showComments, setShowComments] = useState(false);

<ThreadedCommentSection
  entityId="post_123"
  isVisible={showComments}
/>
Why it exists: Ensures event listeners and behaviors are only active when the component is visible, improving performance.

highlightedCommentId

Type: string | undefined | null ID of a specific comment to highlight when the section loads.
<ThreadedCommentSection
  entityId="post_123"
  highlightedCommentId="comment_456"  // This comment will be highlighted
/>
Use cases:
  • Deep-linking from notifications
  • Jumping to a specific comment from a URL param
  • Drawing attention to a particular comment
What happens:
  • The component scrolls to the highlighted comment
  • The comment is visually highlighted (background color change)
  • Highlight fades after a few seconds

theme

Type: 'light' | 'dark' Default: 'light' Only for styled (inline styles) variant. Sets the color theme for the entire comment section.
const [isDark, setIsDark] = useState(false);

<ThreadedCommentSection
  entityId="post_123"
  theme={isDark ? 'dark' : 'light'}
/>
  • Inline Styles Variant
  • Tailwind Variant
Uses this prop. Component checks theme prop and conditionally renders dark or light colors:
style={{
  backgroundColor: theme === 'dark' ? '#1F2937' : '#FFFFFF'
}}
Wire it to your app’s theme state for synchronized dark mode.

children

Type: React.ReactNode Optional React node(s) rendered within the comment feed area.
<ThreadedCommentSection entityId="post_123">
  <div className="text-center text-gray-500 my-4">
    💬 Join the discussion!
  </div>
</ThreadedCommentSection>
Use for: Custom messaging, banners, or UI elements within the comment section.

Complete Examples

Minimal Usage

<ThreadedCommentSection
  foreignId="blog-post-123"
/>
That’s it! Works perfectly with just this.

With Dark Mode (Inline Styles)

import { useState } from 'react';
import { ThreadedCommentSection } from './components/comments-threaded';

function BlogPost({ post }) {
  const [isDark, setIsDark] = useState(false);

  return (
    <>
      <button onClick={() => setIsDark(!isDark)}>
        Toggle Theme
      </button>

      <ThreadedCommentSection
        foreignId={post.id}
        theme={isDark ? 'dark' : 'light'}
      />
    </>
  );
}

With Highlighted Comment

import { useSearchParams } from 'react-router-dom';
import { ThreadedCommentSection } from './components/comments-threaded';

function BlogPost({ post }) {
  const [searchParams] = useSearchParams();
  const highlightedId = searchParams.get('commentId');

  return (
    <ThreadedCommentSection
      foreignId={post.id}
      highlightedCommentId={highlightedId}
    />
  );
}

// URL: /blog/my-post?commentId=comment_abc123
// Will highlight comment_abc123

Full Example with All Props

import { useSearchParams } from 'react-router-dom';
import { ThreadedCommentSection } from './components/comments-threaded';
import { useFetchEntity } from '@replyke/react-js';

function BlogPost({ postId }) {
  const [searchParams] = useSearchParams();
  const [showComments, setShowComments] = useState(true);
  const [isDark, setIsDark] = useState(false);

  const { data: entity } = useFetchEntity({ foreignId: postId });

  return (
    <>
      <button onClick={() => setShowComments(!showComments)}>
        {showComments ? 'Hide' : 'Show'} Comments
      </button>

      <ThreadedCommentSection
        entity={entity}  // Using full entity object
        isVisible={showComments}
        highlightedCommentId={searchParams.get('commentId')}
        theme={isDark ? 'dark' : 'light'}
      >
        <div className="text-center text-sm text-gray-500 my-2">
          💬 Be respectful in the discussion
        </div>
      </ThreadedCommentSection>
    </>
  );
}

TypeScript Support

The component is fully typed. Import types if needed:
import type { ThreadedCommentSectionProps } from './components/comments-threaded';

const props: ThreadedCommentSectionProps = {
  entityId: 'entity_123',
  theme: 'dark',
};

Next Steps