Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.replyke.com/llms.txt

Use this file to discover all available pages before exploring further.

Adding Features

Extend components with custom behavior — confirmations, analytics, integrations, and more.

Add Confirmation Before Delete

// File: comment-menu-modal-owner.tsx

const handleDelete = () => {
  if (window.confirm('Are you sure you want to delete this comment?')) {
    // existing delete logic
    deleteComment(comment.id);
  }
};
Or use a custom modal by replacing the window.confirm with your modal component.

Add Character Counter to Comment Form

// File: new-comment-form.tsx

const [text, setText] = useState('');
const MAX_LENGTH = 500;

return (
  <div>
    <textarea
      value={text}
      onChange={(e) => setText(e.target.value)}
      maxLength={MAX_LENGTH}
      placeholder="Leave a comment..."
    />
    <div className="text-sm text-gray-400 text-right">
      {text.length} / {MAX_LENGTH}
    </div>
    <button type="submit">Comment</button>
  </div>
);

Add Analytics Tracking

// File: vote-buttons.tsx

const handleUpvote = () => {
  analytics.track('Comment Upvoted', {
    commentId: comment.id,
    entityId: entity.id,
  });
  // existing upvote logic
};
// File: new-comment-form.tsx

const handleSubmit = async () => {
  await submitComment(text);
  analytics.track('Comment Posted', { entityId: entity.id });
};

Add Custom User Badges

// File: single-comment.tsx

<div className="flex items-center gap-2">
  <span className="font-semibold">{author.name}</span>
  {author.isPro && (
    <span className="px-2 py-0.5 bg-amber-500 text-white text-xs rounded-full">
      PRO
    </span>
  )}
  {author.isAdmin && (
    <span className="px-2 py-0.5 bg-purple-600 text-white text-xs rounded-full">
      Admin
    </span>
  )}
</div>

Auto-Collapse Old Threads

// File: comment-thread.tsx

const [isCollapsed, setIsCollapsed] = useState(() => {
  const sevenDaysAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;
  return new Date(comment.createdAt).getTime() < sevenDaysAgo;
});

The hooks expose callback props for user interactions. Wire them to your router:
// File: hooks/use-threaded-comments.tsx

const otherUserClickCallback = (userId: string, foreignId?: string) => {
  // Navigate to user profile
  router.push(`/users/${foreignId || userId}`);
};

const loginRequiredCallback = () => {
  // Redirect to login
  router.push('/login?returnTo=' + window.location.pathname);
};

Add Pinned Comment

Show a pinned comment above the feed:
// File: threaded-comment-section.tsx

return (
  <div>
    <NewCommentForm />

    {pinnedComment && (
      <div className="border-l-4 border-blue-500 pl-4 mb-4 bg-blue-50 dark:bg-blue-950 rounded-r-lg py-2">
        <span className="text-xs font-semibold text-blue-600 uppercase tracking-wide">Pinned</span>
        <SingleComment comment={pinnedComment} />
      </div>
    )}

    <CommentsFeed />
  </div>
);

Add “Load More” Button Instead of Infinite Scroll

In comments-feed.tsx, replace the infinite scroll observer with an explicit button:
{hasNextPage && (
  <button
    onClick={() => fetchNextPage()}
    disabled={isFetchingNextPage}
    className="w-full py-2 text-blue-600 hover:underline text-sm"
  >
    {isFetchingNextPage ? 'Loading...' : 'Load more comments'}
  </button>
)}

Integrate with Error Tracking

// File: use-threaded-comments.tsx

const submitComment = async (text: string) => {
  try {
    await createComment({ content: text });
  } catch (error) {
    Sentry.captureException(error, {
      tags: { feature: 'comments', entityId: entity.id }
    });
    throw error;
  }
};

Next Steps

Advanced

Advanced customization techniques

Colors & Theming

Customize colors and dark mode

Layout & Structure

Modify layout

File Structure

Threaded comments file organization