Building a Bluesky Comments Web Component: Bringing Conversations to Life

In the ever-evolving world of social media, Bluesky has emerged as an exciting decentralized alternative to traditional platforms. As a developer passionate about creating interactive web experiences, I set out to build a custom web component that could seamlessly integrate Bluesky post comments into any website.

Credits

This project was started by Emily Liu, who came up with the idea of using a Bluesky thread as a comments thread. Cory Zue expanded on the idea by removing lots of NextJS dependencies. However it still required a lot of React dependencies, which was why I started creating a web component based version. Lots of developers use static sites for blogs, this works great for static sites, reducing the JS size by 98.5%!

The Motivation

Web components offer a powerful way to create reusable, encapsulated UI elements. My goal was to create a simple, lightweight component that could:

Key Technical Challenges

1. Fetching Comments via Bluesky's Public API

The first hurdle was interfacing with Bluesky's public API. The fetchThread method became the cornerstone of the component:

async fetchThread(uri) {
  const url = `https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread?uri=${encodeURIComponent(uri)}`;
  
  const response = await fetch(url, {
    method: "GET",
    headers: { Accept: "application/json" },
    cache: "no-store"
  });

  if (!response.ok) {
    throw new Error(`Failed to fetch thread: ${response.statusText}`);
  }

  return await response.json();
}

2. Creating a Flexible Rendering Approach

The render method had to be both powerful and flexible. I implemented a sorting mechanism to prioritize high-engagement comments and added a "Show more" functionality:

render() {
  const sortedReplies = this.thread.replies.sort(
    (a, b) => (b.post.likeCount ?? 0) - (a.post.likeCount ?? 0)
  );

  // Render initial comments and provide expand functionality
  sortedReplies.slice(0, this.visibleCount).forEach((reply) => {
    commentsContainer.appendChild(this.createCommentElement(reply));
  });
}

3. Security and Styling Considerations

I implemented several key features to ensure security and flexibility:

Lessons Learned

  1. API Interaction: Working with public APIs requires robust error handling and flexible parsing.
  2. Web Components: They provide an elegant way to create reusable, framework-agnostic UI elements.
  3. Performance: Implementing features like lazy loading helps manage larger comment threads.

Code Highlights

The component uses several modern web APIs:

Customization Options

The component supports several customization methods:

Future Improvements

While the current implementation is functional, there's room for enhancement:

Conclusion

Building this Bluesky comments web component was an exciting journey into modern web development. It demonstrates the power of web components in creating modular, reusable UI elements that can work across different frameworks and websites.

Usage Example

<bsky-comments post="at://did:plc:user/collection/postid"></bsky-comments>

By leveraging web standards and Bluesky's public API, we've created a simple yet powerful way to embed social discussions into any web page.