bluesky-comments-tag is a JavaScript SDK for building applications with Bluesky and AT Protocol.
A lightweight, customizable web component to use Bluesky for your website comments.
Load the script from a CDN and then use the tag in your HTML:
<!-- Use the element -->
<bluesky-comments url="https://bsky.app/profile/mk.gg/post/3lb3cxyeh3c2f">
</bluesky-comments>
<!-- Include the script tag anywhere -->
<script type="module">
import "https://esm.sh/bluesky-comments-tag/load";
</script>
The component can be customized in two ways:
bluesky-comments {
/* Colors */
--bluesky-text-color: #333;
--bluesky-handle-color: #888;
--bluesky-footer-text-color: rgb(111, 134, 159);
--bluesky-bg-color: #fff;
--bluesky-hover-bg: #f0f0f0;
--bluesky-border-color: #e0e0e0;
/* Typography */
--bluesky-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
"Helvetica Neue", Arial, sans-serif;
--bluesky-font-size: 14px;
--bluesky-footer-font-size: 14px;
}
@media (prefers-color-scheme: dark) {
bluesky-comments {
--bluesky-bg-color: #1e293b;
--bluesky-text-color: #e2e8f0;
--bluesky-border-color: #4a5568;
--bluesky-hover-bg: #2d3748;
--bluesky-handle-color: #9ca3af;
--bluesky-footer-text-color: #9ca3af;
}
}
The component exposes several parts that can be styled directly using the ::part() selector:
bluesky-comments::part(avatar) {
border: 2px solid gold;
}
bluesky-comments::part(comment-header) {
background: #f8f9fa;
}
bluesky-comments::part(comment-body) {
font-size: 1.1em;
}
bluesky-comments::part(comment-content) {
line-height: 1.6;
}
bluesky-comments::part(comment-footer) {
padding: 8px 12px;
}
Available parts:
avatar - The user's avatar image or default avatarcomment-header - The header section containing avatar and user infocomment-body - The main comment content containercomment-content - The text content of the commentcomment-footer - The footer with interaction counts| Property | Default | Description |
|---|---|---|
| --bluesky-font-family | -apple-system, etc. | Font family for all text |
| --bluesky-font-size | 16px | Base font size |
| --bluesky-text-color | #333 | Main text color |
| --bluesky-handle-color | #888 | Username/handle color |
| --bluesky-footer-text-color | rgb(111, 134, 159) | Footer text color |
| --bluesky-bg-color | #fff | Background color |
| --bluesky-hover-bg | #f0f0f0 | Hover state background |
| --bluesky-border-color | #e0e0e0 | Border color |
| --bluesky-spacing-xs | 5px | Extra small spacing |
| --bluesky-spacing-sm | 8px | Small spacing |
| --bluesky-spacing-md | 10px | Medium spacing |
| --bluesky-spacing-lg | 15px | Large spacing |
| --bluesky-avatar-size | 24px | Size of avatar images |
| --bluesky-avatar-bg | #e0e0e0 | Default avatar background |
| --bluesky-reply-border-width | 2px | Reply border width |
| --bluesky-footer-font-size | 15px | Footer text size |
| --bluesky-icon-size | 18px | Size of footer icons |
Take these with a pinch of salt: Claude made them up. You can use these as a starting point for your own custom themes.
bluesky-comments {
--bluesky-bg-color: #ffffff;
--bluesky-font-family: "Inter", system-ui, sans-serif;
--bluesky-font-size: 15px;
--bluesky-text-color: #1a2b3c;
--bluesky-handle-color: #64748b;
--bluesky-footer-text-color: #94a3b8;
--bluesky-border-color: #e2e8f0;
--bluesky-hover-bg: #f8fafc;
--bluesky-spacing-xs: 8px;
--bluesky-spacing-sm: 12px;
--bluesky-spacing-md: 16px;
--bluesky-avatar-size: 40px;
--bluesky-avatar-bg: #f1f5f9;
--bluesky-reply-border-width: 2px;
--bluesky-footer-font-size: 13px;
--bluesky-icon-size: 16px;
}
/* Optional: Enhanced styling using parts */
bluesky-comments::part(avatar) {
border: 2px solid #fff;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
bluesky-comments::part(comment-content) {
line-height: 1.6;
}
bluesky-comments {
--bluesky-bg-color: #fcfcfc;
--bluesky-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
sans-serif;
--bluesky-font-size: 14px;
--bluesky-text-color: #2c3e50;
--bluesky-handle-color: #718096;
--bluesky-footer-text-color: #a0aec0;
--bluesky-border-color: #edf2f7;
--bluesky-hover-bg: #f7fafc;
--bluesky-spacing-xs: 6px;
--bluesky-spacing-sm: 10px;
--bluesky-spacing-md: 12px;
--bluesky-avatar-size: 32px;
--bluesky-avatar-bg: #edf2f7;
--bluesky-reply-border-width: 1px;
--bluesky-footer-font-size: 12px;
--bluesky-icon-size: 14px;
}
bluesky-comments::part(comment-header) {
padding: 8px 12px;
background: #f8fafc;
border-radius: 4px 4px 0 0;
}
bluesky-comments {
--bluesky-bg-color: #1e1e2e;
--bluesky-font-family: system-ui, sans-serif;
--bluesky-font-size: 14px;
--bluesky-text-color: #cdd6f4;
--bluesky-handle-color: #a6adc8;
--bluesky-footer-text-color: #7f849c;
--bluesky-border-color: #313244;
--bluesky-hover-bg: #181825;
--bluesky-spacing-xs: 6px;
--bluesky-spacing-sm: 10px;
--bluesky-spacing-md: 14px;
--bluesky-avatar-size: 36px;
--bluesky-avatar-bg: #313244;
--bluesky-reply-border-width: 1px;
--bluesky-footer-font-size: 13px;
--bluesky-icon-size: 16px;
}
bluesky-comments::part(comment-header) {
background: rgba(49, 50, 68, 0.5);
}
bluesky-comments::part(avatar) {
border: 1px solid #45475a;
}
bluesky-comments {
--bluesky-bg-color: #ffffff;
--bluesky-font-family: Verdana, arial, helvetica, sans-serif;
--bluesky-font-size: 13px;
--bluesky-text-color: #1c1c1c;
--bluesky-handle-color: #787c7e;
--bluesky-footer-text-color: #787c7e;
--bluesky-border-color: #edeff1;
--bluesky-hover-bg: #f6f7f8;
--bluesky-spacing-xs: 4px;
--bluesky-spacing-sm: 6px;
--bluesky-spacing-md: 8px;
--bluesky-avatar-size: 24px;
--bluesky-avatar-bg: #edeff1;
--bluesky-reply-border-width: 2px;
--bluesky-footer-font-size: 12px;
--bluesky-icon-size: 16px;
}
bluesky-comments::part(comment-content) {
line-height: 1.5;
padding: 4px 0;
}
bluesky-comments::part(comment-footer) {
opacity: 0.8;
}
bluesky-comments {
--bluesky-bg-color: #fffef9;
--bluesky-font-family: Georgia, "Times New Roman", serif;
--bluesky-font-size: 16px;
--bluesky-text-color: #2d3436;
--bluesky-handle-color: #636e72;
--bluesky-footer-text-color: #b2bec3;
--bluesky-border-color: #dfe6e9;
--bluesky-hover-bg: #f5f6fa;
--bluesky-spacing-xs: 8px;
--bluesky-spacing-sm: 12px;
--bluesky-spacing-md: 20px;
--bluesky-avatar-size: 48px;
--bluesky-avatar-bg: #dfe6e9;
--bluesky-reply-border-width: 1px;
--bluesky-footer-font-size: 14px;
--bluesky-icon-size: 18px;
}
bluesky-comments::part(comment-content) {
line-height: 1.7;
letter-spacing: 0.2px;
}
bluesky-comments::part(avatar) {
border-radius: 8px;
}
Did you get "HTMLElement is not defined" error? Make sure you are loading the component in the browser, not in SSR or Node.js. This is a client-only component.
The component uses standard web components and modern JavaScript features.
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - feel free to use this component in your projects.
Dhaaga - An indie SNS app that blends sleek design 💅, useful features ✨ and fun ways to discover and connect 🎉
Fix X/Twitter and Bluesky embeds! Use multiple images, videos, polls, translations and more on Discord, Telegram and others
a collection of lightweight TypeScript packages for AT Protocol, the protocol powering Bluesky.
Unfollowers for Bluesky é uma aplicação web intuitiva que identifica usuários que não seguem de volta um determinado perfil na rede social Bluesky. Com uma interface simples, basta pesquisar pelo nome de usuário desejado, selecioná-lo e a plataforma exibirá rapidamente a lista de não-seguidores.
Git scraping of AT Protocol/Bluesky instances
Git scraping of Bluesky labelers/label providers
Your Brand Here!
50K+ engaged viewers every month
Limited spots available!
📧 Contact us via email🦋 Contact us on Bluesky