Bluesky Embed RSC

Embed Bluesky posts in your app, with graceful fallbacks!

Installation

Install @hamstack/bluesky-embed-rsc via your favorite package manager:


# Install the library and it's peer dependencies
bun install @hamstack/bluesky-embed-rsc \
  @atproto/api \
  date-fns \
  lucide-react
                

# Install the library and it's peer dependencies
bun install @hamstack/bluesky-embed-rsc \
  @atproto/api \
  date-fns \
  lucide-react
                

Usage:

Here's an example of how to set this up with Next.js:

import { BlueskyPost } from "@hamstack/bluesky-embed-rsc";

export default function Home() {
  return (
    <BlueskyPost src="https://bsky.app/profile/matthamlin.me/post/3layiwns2kk2h">
      This post could not be loaded!
    </BlueskyPost>
  );
}
import { BlueskyPost } from "@hamstack/bluesky-embed-rsc";

export default function Home() {
  return (
    <BlueskyPost src="https://bsky.app/profile/matthamlin.me/post/3layiwns2kk2h">
      This post could not be loaded!
    </BlueskyPost>
  );
}

The BlueskyPost component will render the post, or fallback content if the post can't be loaded.

Here's what the output looks like:

Matt Hamlin

Matt Hamlin

@matthamlin.me

Beer and a fish finger sandwich with chips 🙌
Two glasses of beer on a table in a puba fish finger sandwich with a small bowl of chips
11 days agoView on bsky.app
1
1
0
0

Exports:

@hamstack/bluesky-embed-rsc provides the following exports:

Additionally, a updateConfig function is exported to update the configuration at runtime. This can be useful if you're rendering the BlueskyPost" " component in a different framework than Next.js, or you want to customize the icons!

import { updateConfig } from "@hamstack/bluesky-embed-rsc";
import {
  HeartIcon,
  LinkIcon,
  MessageCircleIcon,
  QuoteIcon,
  RepeatIcon,
} from "your-favorite-icon-library";
import Image from "your-favorite-image-library";

// customize the Image component, or the icons used in the embed
updateConfig({
  components: {
    Image: Image,
  },
  icons: {
    Heart: HeartIcon,
    Link: LinkIcon,
    MessageCircle: MessageCircleIcon,
    Quote: QuoteIcon,
    Repeat: RepeatIcon,
  },
  rootClassName: "my-2 mx-auto",
});
import { updateConfig } from "@hamstack/bluesky-embed-rsc";
import {
  HeartIcon,
  LinkIcon,
  MessageCircleIcon,
  QuoteIcon,
  RepeatIcon,
} from "your-favorite-icon-library";
import Image from "your-favorite-image-library";

// customize the Image component, or the icons used in the embed
updateConfig({
  components: {
    Image: Image,
  },
  icons: {
    Heart: HeartIcon,
    Link: LinkIcon,
    MessageCircle: MessageCircleIcon,
    Quote: QuoteIcon,
    Repeat: RepeatIcon,
  },
  rootClassName: "my-2 mx-auto",
});

The default config is:

export let config: Config = {
  components: {
    Image: NextImage,
  },
  icons: {
    // icons from lucide-react
    Heart,
    Link,
    MessageCircle,
    Quote,
    Repeat,
  },
  rootClassName: "",
};
export let config: Config = {
  components: {
    Image: NextImage,
  },
  icons: {
    // icons from lucide-react
    Heart,
    Link,
    MessageCircle,
    Quote,
    Repeat,
  },
  rootClassName: "",
};

Features:

The BlueskyPost component is a server component, so it can be used in any React Server Component compatible framework (e.g. Next, Remix, Waku, etc.).

The component will render the post, or fallback content (see the children prop) if the post can't be loaded.

Additionally, the component will "expand" (e.g. render inline previews) post embeds, currently limited to images and external links!

Here's an example post that shows an embedded preview to another website: