PostButton
Create on-chain social posts on the Bitcoin blockchain using the bSocial protocol
PostButton
A component for creating on-chain social posts on the Bitcoin blockchain using the bSocial protocol. Provides a rich text editor with markdown support and content type selection.
Installation
npx bigblocks add post-button
Import
import { PostButton } from 'bigblocks';
Props
Prop | Type | Required | Default | Description |
---|---|---|---|---|
onPost | (post: PostTransaction) => void | No | - | Callback after posting |
defaultContent | string | No | - | Default content in editor |
placeholder | string | No | - | Input placeholder text |
maxLength | number | No | - | Character limit |
triggerText | string | No | 'Post' | Button text |
showContentTypeSelector | boolean | No | false | Show content type dropdown |
enableMarkdown | boolean | No | false | Enable markdown support |
className | string | No | - | Additional CSS classes |
variant | string | No | - | Button variant |
size | string | No | - | Button size |
disabled | boolean | No | false | Disable posting |
Basic Usage
import { PostButton } from 'bigblocks';
export default function SocialFeed() {
const handlePost = (post) => {
console.log('New post created:', post);
// Refresh feed or add to state
};
return (
<PostButton
onPost={handlePost}
placeholder="What's on your mind?"
/>
);
}
Advanced Usage
With Custom Configuration
import { PostButton } from 'bigblocks';
export default function CustomPostButton() {
return (
<PostButton
placeholder="Share your thoughts..."
maxLength={500}
triggerText="Share"
showContentTypeSelector={true}
enableMarkdown={true}
onPost={(post) => {
console.log('Posted:', post);
toast.success('Post created successfully!');
}}
/>
);
}
With Default Content
import { PostButton } from 'bigblocks';
export default function PrefilledPost() {
return (
<PostButton
defaultContent="Check out this awesome project!"
placeholder="Add your thoughts..."
onPost={(post) => {
// Handle post creation
addToFeed(post);
}}
/>
);
}
Different Variants and Sizes
import { PostButton } from 'bigblocks';
export default function StyledPostButtons() {
return (
<div className="space-y-4">
<PostButton
size="small"
variant="outline"
triggerText="Quick Post"
onPost={handlePost}
/>
<PostButton
size="medium"
variant="solid"
triggerText="Post"
onPost={handlePost}
/>
<PostButton
size="large"
variant="ghost"
triggerText="Share Story"
onPost={handlePost}
/>
</div>
);
}
With Markdown Support
import { PostButton } from 'bigblocks';
export default function MarkdownPost() {
return (
<PostButton
enableMarkdown={true}
placeholder="Write your post with **markdown** support..."
maxLength={1000}
onPost={(post) => {
console.log('Markdown post:', post);
}}
/>
);
}
Content Type Selection
import { PostButton } from 'bigblocks';
export default function ContentTypePost() {
return (
<PostButton
showContentTypeSelector={true}
placeholder="Select content type and write..."
onPost={(post) => {
console.log('Post type:', post.contentType);
console.log('Content:', post.content);
}}
/>
);
}
Common Patterns
In Social Feed
import { PostButton, SocialFeed } from 'bigblocks';
import { useState } from 'react';
export default function SocialApp() {
const [posts, setPosts] = useState([]);
const handleNewPost = (post) => {
// Add to feed immediately (optimistic update)
setPosts(prevPosts => [post, ...prevPosts]);
// Analytics
analytics.track('post_created', {
contentLength: post.content.length,
hasMarkdown: post.enableMarkdown
});
};
return (
<div className="max-w-2xl mx-auto">
<div className="mb-6">
<PostButton
placeholder="What's happening?"
onPost={handleNewPost}
enableMarkdown={true}
/>
</div>
<SocialFeed posts={posts} />
</div>
);
}
Reply to Post
import { PostButton } from 'bigblocks';
export default function ReplyButton({ parentPost }) {
return (
<PostButton
placeholder={`Reply to ${parentPost.author.name}...`}
triggerText="Reply"
size="small"
defaultContent={`@${parentPost.author.name} `}
onPost={(reply) => {
// Handle reply
addReply(parentPost.txid, reply);
}}
/>
);
}
With Error Handling
import { PostButton } from 'bigblocks';
import { useState } from 'react';
export default function ErrorHandlingPost() {
const [error, setError] = useState(null);
const handlePost = async (post) => {
try {
setError(null);
// Post to blockchain
const result = await createPost(post);
console.log('Post successful:', result);
toast.success('Post created on blockchain!');
} catch (err) {
setError(err.message);
if (err.code === 'INSUFFICIENT_FUNDS') {
toast.error('Insufficient BSV balance for posting');
} else {
toast.error('Failed to create post');
}
}
};
return (
<div>
{error && (
<div className="bg-red-100 text-red-700 p-3 rounded mb-4">
{error}
</div>
)}
<PostButton
onPost={handlePost}
placeholder="Share your thoughts..."
/>
</div>
);
}
Custom Styling
import { PostButton } from 'bigblocks';
export default function CustomStyledPost() {
return (
<PostButton
className="bg-gradient-to-r from-purple-500 to-pink-500 text-white rounded-xl"
placeholder="Create something amazing..."
triggerText="✨ Create"
onPost={(post) => {
console.log('Styled post:', post);
}}
/>
);
}
Character Counter
import { PostButton } from 'bigblocks';
export default function LimitedPost() {
return (
<PostButton
maxLength={280}
placeholder="Share in 280 characters or less..."
triggerText="Tweet"
onPost={(post) => {
if (post.content.length > 280) {
toast.error('Post too long!');
return;
}
handlePost(post);
}}
/>
);
}
Post Transaction Type
interface PostTransaction {
txid: string; // Transaction ID on blockchain
content: string; // Post content
contentType?: string; // Content type if selector enabled
author: {
idKey: string; // BAP identity key
name?: string; // Author name
address: string; // Bitcoin address
};
timestamp: number; // Creation timestamp
block?: {
height: number; // Block height
hash: string; // Block hash
};
fee: number; // Transaction fee in satoshis
confirmed: boolean; // Confirmation status
}
Features
- Blockchain Storage: Posts are permanently stored on Bitcoin blockchain
- Markdown Support: Rich text formatting with markdown
- Content Types: Selectable content types for structured posts
- Character Limits: Configurable maximum length
- Real-time Preview: Preview formatted content before posting
- Optimistic Updates: Immediate UI feedback
- Error Handling: Comprehensive error states
Content Types
When showContentTypeSelector
is enabled, users can select:
- Text: Plain text posts
- Markdown: Formatted text with markdown
- Code: Code snippets with syntax highlighting
- Quote: Quoted text or citations
- Announcement: Important announcements
- Question: Questions for community
- Answer: Answers to questions
Requirements
- Authentication: User must be authenticated with BigBlocks
- Wallet Balance: Sufficient BSV for transaction fees
- Network: Connection to Bitcoin network
- Provider Context: Must be wrapped in BitcoinQueryProvider
Styling
The component uses Radix Themes and can be customized:
/* Custom post button styles */
.post-button {
min-height: 120px;
}
.post-editor {
resize: vertical;
font-family: inherit;
}
.content-type-selector {
margin-bottom: 0.5rem;
}
.character-counter {
text-align: right;
font-size: 0.875rem;
color: var(--gray-11);
}
.character-counter.over-limit {
color: var(--red-11);
}
Best Practices
- Content Guidelines: Encourage meaningful content
- Fee Management: Inform users about posting costs
- Error Feedback: Provide clear error messages
- Optimistic Updates: Show posts immediately
- Character Limits: Set reasonable limits for readability
Troubleshooting
Posts Not Appearing
- Check user authentication status
- Verify wallet has sufficient balance
- Ensure network connectivity
- Check for transaction confirmation
Markdown Not Rendering
- Verify
enableMarkdown
is true - Check markdown syntax
- Ensure preview is working
Content Type Issues
- Verify
showContentTypeSelector
is enabled - Check default content type selection
- Ensure proper type validation
Related Components
- SocialFeed - Display posts
- PostCard - Individual post display
- LikeButton - Like posts
- FollowButton - Follow users
API Integration
The component integrates with bSocial protocol APIs:
// Post creation endpoint
POST /api/social/posts
{
content: string;
contentType?: string;
replyTo?: string;
}
// Response
{
txid: string;
post: PostTransaction;
fee: number;
}
Notes for Improvement
Focused Implementation: The actual component is more focused than the prompt described:
- Uses bmap-api-types for proper Bitcoin transaction integration
- Includes content type selection and markdown support
- Simpler props interface focused on essential functionality
- No built-in media upload (handled separately)
- Direct integration with blockchain posting services