···
import { AtProtoProvider } from "../lib/providers/AtProtoProvider";
-
import { AtProtoRecord } from "../lib/core/AtProtoRecord";
import { TangledString } from "../lib/components/TangledString";
import { LeafletDocument } from "../lib/components/LeafletDocument";
import { BlueskyProfile } from "../lib/components/BlueskyProfile";
···
-
const customComponentSnippet = `import { useLatestRecord, useColorScheme, AtProtoRecord } from 'atproto-ui';
import type { FeedPostRecord } from 'atproto-ui';
-
const LatestPostSummary: React.FC<{ did: string }> = ({ did }) => {
-
const scheme = useColorScheme('system');
-
const { rkey, loading, error } = useLatestRecord<FeedPostRecord>(did, 'app.bsky.feed.post');
if (loading) return <span>Loading…</span>;
-
if (error || !rkey) return <span>No post yet.</span>;
-
<AtProtoRecord<FeedPostRecord>
-
collection="app.bsky.feed.post"
-
renderer={({ record }) => (
-
<article data-color-scheme={scheme}>
-
<strong>{record?.text ?? 'Empty post'}</strong>
const codeBlockBase: React.CSSProperties = {
···
const basicCodeRef = useRef<HTMLElement | null>(null);
const customCodeRef = useRef<HTMLElement | null>(null);
loading: loadingLatestPost,
-
} = useLatestRecord<unknown>(did, BLUESKY_POST_COLLECTION);
const quoteSampleDid = "did:plc:ttdrpj45ibqunmfhdsb4zdwq";
const quoteSampleRkey = "3m2prlq6xxc2v";
···
<div style={columnStackStyle}>
<section style={panelStyle}>
<h3 style={sectionHeaderStyle}>
···
-
{!loadingLatestPost && latestPostRkey && (
colorScheme={colorSchemePreference}
···
<section style={{ ...panelStyle, marginTop: 32 }}>
-
<h3 style={sectionHeaderStyle}>Build your own component</h3>
<p style={{ color: mutedTextColor, margin: "4px 0 8px" }}>
Wrap your app with the provider once and drop the ready-made
components wherever you need them.
···
<p style={{ color: mutedTextColor, margin: "16px 0 8px" }}>
-
Need to make your own component? Compose your own renderer
-
with the hooks and utilities that ship with the library.
<pre style={codeBlockStyle}>
···
-
{customComponentSnippet}
-
flexDirection: "column",
-
<p style={{ color: mutedTextColor, margin: 0 }}>
-
Live example with your handle:
-
colorScheme={colorSchemePreference}
-
const LatestPostSummary: React.FC<{
-
colorScheme: ColorSchemePreference;
-
}> = ({ did, colorScheme }) => {
-
const { record, rkey, loading, error } = useLatestRecord<FeedPostRecord>(
-
BLUESKY_POST_COLLECTION,
-
const scheme = useColorScheme(colorScheme);
-
? latestSummaryPalette.dark
-
: latestSummaryPalette.light;
-
if (loading) return <div style={palette.muted}>Loading summary…</div>;
-
return <div style={palette.error}>Failed to load the latest post.</div>;
-
if (!rkey) return <div style={palette.muted}>No posts published yet.</div>;
-
const atProtoProps = record
-
: { did, collection: "app.bsky.feed.post", rkey };
-
<AtProtoRecord<FeedPostRecord>
-
renderer={({ record: resolvedRecord }) => (
-
<article data-color-scheme={scheme}>
-
<strong>{resolvedRecord?.text ?? "Empty post"}</strong>
const sectionHeaderStyle: React.CSSProperties = {
···
const loadingBox: React.CSSProperties = { padding: 8 };
const errorBox: React.CSSProperties = { padding: 8, color: "crimson" };
const infoBox: React.CSSProperties = { padding: 8, color: "#555" };
-
const latestSummaryPalette = {
-
border: "1px solid #e2e8f0",
-
flexDirection: "column",
-
} satisfies React.CSSProperties,
-
alignItems: "baseline",
-
justifyContent: "space-between",
-
} satisfies React.CSSProperties,
-
} satisfies React.CSSProperties,
-
whiteSpace: "pre-wrap",
-
} satisfies React.CSSProperties,
-
textDecoration: "none",
-
} satisfies React.CSSProperties,
-
} satisfies React.CSSProperties,
-
} satisfies React.CSSProperties,
-
border: "1px solid #1e293b",
-
flexDirection: "column",
-
} satisfies React.CSSProperties,
-
alignItems: "baseline",
-
justifyContent: "space-between",
-
} satisfies React.CSSProperties,
-
} satisfies React.CSSProperties,
-
whiteSpace: "pre-wrap",
-
} satisfies React.CSSProperties,
-
textDecoration: "none",
-
} satisfies React.CSSProperties,
-
} satisfies React.CSSProperties,
-
} satisfies React.CSSProperties,
export const App: React.FC = () => {
···
import { AtProtoProvider } from "../lib/providers/AtProtoProvider";
import { TangledString } from "../lib/components/TangledString";
import { LeafletDocument } from "../lib/components/LeafletDocument";
import { BlueskyProfile } from "../lib/components/BlueskyProfile";
···
+
const prefetchedDataSnippet = `import { BlueskyPost, useLatestRecord } from 'atproto-ui';
import type { FeedPostRecord } from 'atproto-ui';
+
const LatestPostWithPrefetch: React.FC<{ did: string }> = ({ did }) => {
+
// Fetch once with the hook
+
const { record, rkey, loading } = useLatestRecord<FeedPostRecord>(
if (loading) return <span>Loading…</span>;
+
if (!record || !rkey) return <span>No posts yet.</span>;
+
// Pass prefetched record—BlueskyPost won't re-fetch it
+
return <BlueskyPost did={did} rkey={rkey} record={record} />;
const codeBlockBase: React.CSSProperties = {
···
const basicCodeRef = useRef<HTMLElement | null>(null);
const customCodeRef = useRef<HTMLElement | null>(null);
+
// Latest Bluesky post - fetch with record for prefetch demo
+
record: latestPostRecord,
loading: loadingLatestPost,
+
} = useLatestRecord<FeedPostRecord>(did, BLUESKY_POST_COLLECTION);
const quoteSampleDid = "did:plc:ttdrpj45ibqunmfhdsb4zdwq";
const quoteSampleRkey = "3m2prlq6xxc2v";
···
<div style={columnStackStyle}>
<section style={panelStyle}>
<h3 style={sectionHeaderStyle}>
+
Latest Post (Prefetched Data)
+
<p style={{ fontSize: 12, color: mutedTextColor, margin: "0 0 8px" }}>
+
Using <code style={{ background: scheme === "dark" ? "#1e293b" : "#e2e8f0", padding: "2px 4px", borderRadius: 3 }}>useLatestRecord</code> to fetch once, then passing <code style={{ background: scheme === "dark" ? "#1e293b" : "#e2e8f0", padding: "2px 4px", borderRadius: 3 }}>record</code> prop—no re-fetch!
···
+
{!loadingLatestPost && latestPostRkey && latestPostRecord && (
+
record={latestPostRecord}
colorScheme={colorSchemePreference}
···
<section style={{ ...panelStyle, marginTop: 32 }}>
+
<h3 style={sectionHeaderStyle}>Code Examples</h3>
<p style={{ color: mutedTextColor, margin: "4px 0 8px" }}>
Wrap your app with the provider once and drop the ready-made
components wherever you need them.
···
<p style={{ color: mutedTextColor, margin: "16px 0 8px" }}>
+
Pass prefetched data to components to skip API calls—perfect for SSR or caching.
<pre style={codeBlockStyle}>
···
+
{prefetchedDataSnippet}
const sectionHeaderStyle: React.CSSProperties = {
···
const loadingBox: React.CSSProperties = { padding: 8 };
const errorBox: React.CSSProperties = { padding: 8, color: "crimson" };
const infoBox: React.CSSProperties = { padding: 8, color: "#555" };
export const App: React.FC = () => {