Appearance
React UI Components
@outstand-so/ui is a React component library that provides pre-built UI components and hooks for integrating Outstand's social media API into your React applications. It simplifies the process of building social media management interfaces by providing ready-to-use components for account management, post creation, media uploads, and analytics.
Installation
Install the package from npm:
npm install @outstand-so/uiOr with yarn:
yarn add @outstand-so/uiOr with pnpm:
pnpm add @outstand-so/uiGetting Started
Provider Setup
Wrap your application (or the part that uses Outstand components) with the OutstandProvider:
tsx
import { OutstandProvider } from '@outstand-so/ui';
function App() {
return (
<OutstandProvider apiKey="your-api-key" baseUrl="
{/* Your app components */}
</OutstandProvider>
);
}Props:
apiKey(required): Your Outstand API keybaseUrl(optional): Base URL for API requests. Defaults to `tenantId(optional): Tenant ID for multi-tenant applicationsinitialAccounts(optional): Pre-populate accounts without fetching
Components
Account Management
ConnectAccountButton
A button component that initiates OAuth flow for connecting a social media account.
tsx
import { ConnectAccountButton } from '@outstand-so/ui';
<ConnectAccountButton
network="x"
redirectUri="
apiKey="your-api-key"
onSuccess={(authUrl) => {
window.location.href = authUrl;
}}
onError={(error) => {
console.error('Connection error:', error);
}}
/>Props:
network(required): Social network to connect ("threads" | "bluesky" | "x" | "linkedin" | "youtube" | "instagram" | "facebook" | "tiktok" | "pinterest")redirectUri(required): URL to redirect after OAuth flowapiKey(required): Your API keytenantId(optional): Tenant ID for multi-tenant appsbaseUrl(optional): API base URLonSuccess(optional): Callback when auth URL is obtainedonError(optional): Error handlerclassName(optional): Additional CSS classeschildren(optional): Custom button contentvariant(optional): Button style ("default" | "outline" | "ghost")size(optional): Button size ("sm" | "md" | "lg")
ConnectAccountButtonGroup
Display multiple connection buttons in a group layout.
tsx
import { ConnectAccountButtonGroup } from '@outstand-so/ui';
<ConnectAccountButtonGroup
networks={['x', 'linkedin', 'instagram', 'facebook']}
redirectUri="
apiKey="your-api-key"
layout="grid"
variant="outline"
/>Props:
networks(required): Array of social networks to showredirectUri(required): OAuth callback URLapiKey(required): Your API keylayout(optional): Layout style ("horizontal" | "vertical" | "grid")- Other props same as
ConnectAccountButton
AccountsList
Display a paginated list of connected social accounts with management options.
tsx
import { AccountsList } from '@outstand-so/ui';
<AccountsList
apiKey="your-api-key"
onAccountSelect={(account) => {
console.log('Selected:', account);
}}
onAccountDisconnect={(accountId) => {
console.log('Disconnected:', accountId);
}}
pageSize={20}
/>Props:
apiKey(required): Your API keybaseUrl(optional): API base URLtenantId(optional): Tenant IDonAccountSelect(optional): Callback when account is selectedonAccountDisconnect(optional): Callback when account is disconnectedclassName(optional): Additional CSS classespageSize(optional): Number of accounts per page (default: 20)
AccountCard
Display a single social account card.
tsx
import { AccountCard } from '@outstand-so/ui';
<AccountCard
account={account}
onSelect={() => handleSelect(account)}
onDisconnect={() => handleDisconnect(account.id)}
/>Props:
account(required): SocialAccount objectonSelect(optional): Selection handleronDisconnect(optional): Disconnect handlerclassName(optional): Additional CSS classes
Post Creation
CreatePostForm
A complete form component for creating and scheduling posts.
tsx
import { CreatePostForm } from '@outstand-so/ui';
<CreatePostForm
apiKey="your-api-key"
enableScheduling={true}
enableDrafts={true}
onPostCreated={(post) => {
console.log('Post created:', post);
}}
onError={(error) => {
console.error('Error:', error);
}}
/>Props:
apiKey(required): Your API keybaseUrl(optional): API base URLaccounts(optional): Pre-selected accountsonPostCreated(optional): Callback when post is createdonError(optional): Error handlerclassName(optional): Additional CSS classesenableScheduling(optional): Enable scheduling UI (default: false)enableDrafts(optional): Enable draft saving (default: false)
PostComposer
A rich text editor component for composing post content with character limits and account-specific validation.
tsx
import { PostComposer } from '@outstand-so/ui';
<PostComposer
value={postContent}
onChange={setPostContent}
selectedAccounts={selectedAccounts}
placeholder="What's on your mind?"
maxLength={5000}
/>Props:
value(required): Current post contentonChange(required): Content change handlerselectedAccounts(optional): Selected accounts for validationplaceholder(optional): Placeholder textmaxLength(optional): Maximum character lengthclassName(optional): Additional CSS classes
NetworkSelector
Component for selecting which social accounts to post to.
tsx
import { NetworkSelector } from '@outstand-so/ui';
<NetworkSelector
accounts={accounts}
selectedIds={selectedAccountIds}
onChange={setSelectedAccountIds}
/>Props:
accounts(required): Array of SocialAccount objectsselectedIds(required): Array of selected account IDsonChange(required): Selection change handlerclassName(optional): Additional CSS classes
PostScheduler
Date and time picker for scheduling posts.
tsx
import { PostScheduler } from '@outstand-so/ui';
<PostScheduler
value={scheduledDate}
onChange={setScheduledDate}
minDate={new Date()}
maxDays={30}
/>Props:
value(required): Selected date (Date | null)onChange(required): Date change handlerclassName(optional): Additional CSS classesminDate(optional): Minimum selectable datemaxDays(optional): Maximum days in the future
NetworkConfigPanel
Configure platform-specific options for selected networks.
tsx
import { NetworkConfigPanel } from '@outstand-so/ui';
<NetworkConfigPanel
networks={['instagram', 'youtube', 'tiktok']}
configs={networkConfigs}
onChange={setNetworkConfigs}
/>Props:
networks(required): Array of network namesconfigs(required): Configuration objectonChange(required): Config change handlerclassName(optional): Additional CSS classes
Configuration Options:
- Threads:
{ reply_control?: "everyone" | "accounts_you_follow" | "mentioned_only" } - Instagram:
{ media_type?: "REELS" | "STORIES" | "FEED", share_to_feed?: boolean } - YouTube:
{ title?: string, description?: string, privacy_status?: "public" | "private" | "unlisted", category_id?: string, tags?: string[] } - TikTok:
{ privacy_level?: "PUBLIC_TO_EVERYONE" | "MUTUAL_FOLLOW_FRIENDS" | "SELF_ONLY", disable_duet?: boolean, disable_stitch?: boolean, disable_comment?: boolean }
Media Management
MediaUploader
Component for uploading images and videos.
tsx
import { MediaUploader } from '@outstand-so/ui';
<MediaUploader
apiKey="your-api-key"
onUploadComplete={(media) => {
console.log('Uploaded:', media);
}}
onUploadError={(error) => {
console.error('Upload error:', error);
}}
maxFiles={10}
acceptedTypes={['image/*', 'video/*']}
/>Props:
apiKey(required): Your API keybaseUrl(optional): API base URLonUploadComplete(optional): Callback with uploaded media filesonUploadError(optional): Error handlermaxFiles(optional): Maximum number of files (default: unlimited)acceptedTypes(optional): MIME types to acceptclassName(optional): Additional CSS classes
MediaPreview
Preview a single media file with optional remove action.
tsx
import { MediaPreview } from '@outstand-so/ui';
<MediaPreview
media={mediaFile}
onRemove={() => handleRemove(mediaFile.id)}
progress={uploadProgress}
/>Props:
media(required): MediaFile objectonRemove(optional): Remove handlerprogress(optional): Upload progress (0-100)className(optional): Additional CSS classes
MediaGallery
Display multiple media files in a grid layout.
tsx
import { MediaGallery } from '@outstand-so/ui';
<MediaGallery
media={mediaFiles}
onRemove={(index) => {
setMediaFiles(prev => prev.filter((_, i) => i !== index));
}}
columns={3}
/>Props:
media(required): Array of MediaFile objectsonRemove(optional): Remove handler with indexclassName(optional): Additional CSS classescolumns(optional): Grid columns (2 | 3 | 4, default: 3)
Analytics
PostMetrics
Display analytics for a specific post.
tsx
import { PostMetrics } from '@outstand-so/ui';
<PostMetrics
apiKey="your-api-key"
postId="post-id"
refreshInterval={30000}
/>Props:
apiKey(required): Your API keypostId(required): Post ID to display metrics forbaseUrl(optional): API base URLclassName(optional): Additional CSS classesrefreshInterval(optional): Auto-refresh interval in milliseconds
PostMetricsCard
Display metrics for a single account's post.
tsx
import { PostMetricsCard } from '@outstand-so/ui';
<PostMetricsCard
account={account}
metrics={metricsData}
platformPostId="123456789"
publishedAt="2025-01-15T10:30:00Z"
/>Props:
account(required): Account object with id, nickname, network, usernamemetrics(required): PostMetricsData objectplatformPostId(optional): Platform-specific post IDpublishedAt(optional): Publication timestampclassName(optional): Additional CSS classes
PostsWithMetrics
Display a paginated list of posts with their metrics.
tsx
import { PostsWithMetrics } from '@outstand-so/ui';
<PostsWithMetrics
apiKey="your-api-key"
socialAccountId="account-id"
pageSize={10}
/>Props:
apiKey(required): Your API keybaseUrl(optional): API base URLsocialAccountId(optional): Filter by account IDpageSize(optional): Posts per page (default: 10)className(optional): Additional CSS classes
OAuth Flow
OAuthCallback
Handle OAuth callback and finalize account connections.
tsx
import { OAuthCallback } from '@outstand-so/ui';
<OAuthCallback
apiKey="your-api-key"
onSuccess={(accounts) => {
console.log('Connected accounts:', accounts);
}}
onError={(error) => {
console.error('Connection error:', error);
}}
/>Props:
apiKey(required): Your API keybaseUrl(optional): API base URLonSuccess(optional): Callback with connected accountsonError(optional): Error handlerclassName(optional): Additional CSS classes
PageSelector
Select pages to connect (for networks like Facebook that have multiple pages).
tsx
import { PageSelector } from '@outstand-so/ui';
<PageSelector
network="facebook"
pages={availablePages}
onSelect={(selectedIds) => {
console.log('Selected pages:', selectedIds);
}}
isLoading={false}
/>Props:
network(required): Network namepages(required): Array of available pagesonSelect(required): Selection handlerisLoading(optional): Loading stateclassName(optional): Additional CSS classes
Hooks
useOutstand
Access the Outstand context (accounts, selected accounts, loading state).
import { useOutstand } from '@outstand-so/ui';
function MyComponent() {
const { accounts, selectedAccounts, setSelectedAccounts, isLoading } = useOutstand();
return (
<div>
{accounts.map(account => (
<div key={account.id}>{account.username}</div>
))}
</div>
);
}Returns:
apiKey: Current API keybaseUrl: Base URLtenantId: Tenant IDaccounts: Array of SocialAccountsetAccounts: Update accountsselectedAccounts: Array of selected account IDssetSelectedAccounts: Update selected accountsisLoading: Loading statesetIsLoading: Update loading state
useOutstandApi
Get API client methods for making requests.
import { useOutstandApi } from '@outstand-so/ui';
function MyComponent() {
const api = useOutstandApi({ apiKey: 'your-api-key' });
const fetchAccounts = async () => {
const response = await api.get('/v1/social-accounts');
if (response.success) {
console.log('Accounts:', response.data);
}
};
return <button onClick={fetchAccounts}>Fetch Accounts</button>;
}Returns:
get<T>(endpoint): GET requestpost<T>(endpoint, body): POST requestpatch<T>(endpoint, body): PATCH requestdelete<T>(endpoint): DELETE requestrequest<T>(endpoint, options): Custom request
useAccounts
Fetch and manage social accounts with pagination.
import { useAccounts } from '@outstand-so/ui';
function AccountsComponent() {
const {
accounts,
total,
isLoading,
error,
refetch,
disconnectAccount,
hasNextPage,
hasPrevPage
} = useAccounts({
apiKey: 'your-api-key',
limit: 20,
offset: 0
});
return (
<div>
{accounts.map(account => (
<div key={account.id}>
{account.username}
<button onClick={() => disconnectAccount(account.id)}>
Disconnect
</button>
</div>
))}
</div>
);
}Options:
apiKey(required): Your API keybaseUrl(optional): API base URLtenantId(optional): Tenant IDlimit(optional): Page sizeoffset(optional): Pagination offset
Returns:
accounts: Array of SocialAccounttotal: Total countisLoading: Loading stateerror: Error objectrefetch: Refetch functiondisconnectAccount: Disconnect functionhasNextPage: BooleanhasPrevPage: Boolean
usePosts
Fetch and manage posts with pagination.
import { usePosts } from '@outstand-so/ui';
function PostsComponent() {
const {
posts,
total,
isLoading,
error,
refetch,
createPost,
deletePost,
hasNextPage,
hasPrevPage
} = usePosts({
apiKey: 'your-api-key',
socialAccountId: 'account-id',
limit: 10
});
const handleCreate = async () => {
const response = await createPost({
content: 'Hello world!',
accounts: ['account-id']
});
if (response.success) {
console.log('Post created:', response.data);
}
};
return (
<div>
<button onClick={handleCreate}>Create Post</button>
{posts.map(post => (
<div key={post.id}>
{post.containers[0]?.content}
<button onClick={() => deletePost(post.id)}>Delete</button>
</div>
))}
</div>
);
}Options:
apiKey(required): Your API keybaseUrl(optional): API base URLsocialAccountId(optional): Filter by accountlimit(optional): Page sizeoffset(optional): Pagination offset
Returns:
posts: Array of Posttotal: Total countisLoading: Loading stateerror: Error objectrefetch: Refetch functioncreatePost: Create post functiondeletePost: Delete post functionhasNextPage: BooleanhasPrevPage: Boolean
usePostMetrics
Fetch analytics for a specific post.
import { usePostMetrics } from '@outstand-so/ui';
function MetricsComponent({ postId }: { postId: string }) {
const {
analytics,
isLoading,
error,
refetch
} = usePostMetrics({
apiKey: 'your-api-key',
postId,
refreshInterval: 30000
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<p>Total Likes: {analytics?.aggregated_metrics.total_likes}</p>
<p>Total Views: {analytics?.aggregated_metrics.total_views}</p>
</div>
);
}Options:
apiKey(required): Your API keypostId(required): Post IDbaseUrl(optional): API base URLrefreshInterval(optional): Auto-refresh interval in ms
Returns:
analytics: PostAnalytics object or nullisLoading: Loading stateerror: Error objectrefetch: Refetch function
useMediaUpload
Upload media files to Outstand.
import { useMediaUpload } from '@outstand-so/ui';
function UploadComponent() {
const {
uploadFile,
uploadFiles,
getUploadUrl,
isUploading,
uploadProgress
} = useMediaUpload({
apiKey: 'your-api-key'
});
const handleUpload = async (file: File) => {
const mediaFile = await uploadFile(file);
if (mediaFile) {
console.log('Uploaded:', mediaFile);
}
};
return (
<div>
<input
type="file"
onChange={(e) => {
const file = e.target.files?.[0];
if (file) handleUpload(file);
}}
/>
{isUploading && <div>Uploading... {uploadProgress[file.name]}%</div>}
</div>
);
}Options:
apiKey(required): Your API keybaseUrl(optional): API base URL
Returns:
uploadFile: Upload single fileuploadFiles: Upload multiple filesgetUploadUrl: Get upload URLisUploading: Uploading stateuploadProgress: Progress by filename
useOAuthFlow
Manage OAuth flow for connecting accounts.
import { useOAuthFlow } from '@outstand-so/ui';
function OAuthComponent() {
const {
getAuthUrl,
getPendingConnection,
finalizeConnection,
isLoading
} = useOAuthFlow({
apiKey: 'your-api-key'
});
const handleConnect = async () => {
const response = await getAuthUrl('x', '
if (response.success && response.data) {
window.location.href = response.data.auth_url;
}
};
return (
<button onClick={handleConnect} disabled={isLoading}>
Connect X Account
</button>
);
}Options:
apiKey(required): Your API keybaseUrl(optional): API base URL
Returns:
getAuthUrl: Get OAuth URLgetPendingConnection: Get pending connection detailsfinalizeConnection: Finalize connectionisLoading: Loading state
TypeScript Types
The package exports comprehensive TypeScript types:
import type {
SocialAccount,
SocialNetwork,
Post,
PostContainer,
PostSocialAccount,
MediaFile,
PostAnalytics,
PostMetricsData,
CreatePostRequest,
ApiResponse,
PaginatedResponse,
// ... and more
} from '@outstand-so/ui';Key Types:
SocialNetwork: Union type of supported networksSocialAccount: Account object structurePost: Post object structureMediaFile: Media file structurePostAnalytics: Analytics data structureCreatePostRequest: Post creation payloadApiResponse<T>``: Standard API response wrapper
Examples
Complete Post Creation Flow
tsx
import {
OutstandProvider,
CreatePostForm,
AccountsList
} from '@outstand-so/ui';
function PostManager() {
return (
<OutstandProvider apiKey="your-api-key">
<div>
<h2>Connected Accounts</h2>
<AccountsList apiKey="your-api-key" />
<h2>Create Post</h2>
<CreatePostForm
apiKey="your-api-key"
enableScheduling={true}
onPostCreated={(post) => {
alert(`Post created: ${post.id}`);
}}
/>
</div>
</OutstandProvider>
);
}Custom Post Creation with Individual Components
import {
OutstandProvider,
PostComposer,
NetworkSelector,
MediaUploader,
PostScheduler,
NetworkConfigPanel,
useAccounts
} from '@outstand-so/ui';
function CustomPostCreator() {
const { accounts } = useAccounts({ apiKey: 'your-api-key' });
const [content, setContent] = useState('');
const [selectedIds, setSelectedIds] = useState<string[]>([]);
const [media, setMedia] = useState<MediaFile[]>([]);
const [scheduledAt, setScheduledAt] = useState<Date | null>(null);
const handleSubmit = async () => {
// Use usePosts hook to create post
// ...
};
return (
<div>
<PostComposer
value={content}
onChange={setContent}
selectedAccounts={accounts.filter(a => selectedIds.includes(a.id))}
/>
<NetworkSelector
accounts={accounts}
selectedIds={selectedIds}
onChange={setSelectedIds}
/>
<MediaUploader
apiKey="your-api-key"
onUploadComplete={setMedia}
/>
<PostScheduler
value={scheduledAt}
onChange={setScheduledAt}
/>
<NetworkConfigPanel
networks={[...new Set(accounts.filter(a => selectedIds.includes(a.id)).map(a => a.network))]}
configs={{}}
onChange={() => {}}
/>
<button onClick={handleSubmit}>Create Post</button>
</div>
);
}View Post Analytics
tsx
import { PostMetrics, PostsWithMetrics } from '@outstand-so/ui';
function AnalyticsDashboard() {
const [selectedPostId, setSelectedPostId] = useState<string | null>(null);
return (
<div>
{selectedPostId ? (
<PostMetrics
apiKey="your-api-key"
postId={selectedPostId}
refreshInterval={30000}
/>
) : (
<PostsWithMetrics
apiKey="your-api-key"
pageSize={10}
/>
)}
</div>
);
}Learn More
- Check out the playground example to see all components in action
- View the package on npm
Tool Reference\ \ Previous Page X (Twitter) — Token Refresh Failures\ \ Next Page
On this page
Installation Getting Started Provider Setup Components Account Management ConnectAccountButton ConnectAccountButtonGroup AccountsList AccountCard Post Creation CreatePostForm PostComposer NetworkSelector PostScheduler NetworkConfigPanel Media Management MediaUploader MediaPreview MediaGallery Analytics PostMetrics PostMetricsCard PostsWithMetrics OAuth Flow OAuthCallback PageSelector Hooks useOutstand useOutstandApi useAccounts usePosts usePostMetrics useMediaUpload useOAuthFlow TypeScript Types Examples Complete Post Creation Flow Custom Post Creation with Individual Components View Post Analytics Learn More