Request cancellation
fetchSite and fetchArticle both accept an optional AbortSignal as a third argument. When the signal fires, any in-flight HTTP requests are cancelled immediately.
fetchSite(author, siteSlug, signal?)fetchArticle(author, articleSlug, signal?)When you need this
Section titled “When you need this”In server contexts, passing the request’s signal ensures the Scribe PDS fetch is cancelled if the user navigates away before your loader responds. Without it, the server continues fetching data after the response is no longer needed.
In client contexts, passing a signal from an AbortController lets you cancel the fetch on component unmount or when parameters change.
Framework adapters wire this up automatically
Section titled “Framework adapters wire this up automatically”If you are using a framework adapter (@scribe-atp/react, @scribe-atp/angular, etc.), you do not need to manage signals manually:
- React hooks (
useSite,useArticle) — abort on unmount and on parameter change - Angular signals (
injectSite,injectArticle) — abort when the host component is destroyed - Angular Observable (
ScribeService) — abort when you unsubscribe or whenasyncpipe’s component is destroyed - Vue composables — abort on unmount and on parameter change
- Nuxt composables — handled by
useAsyncData
Only read on if you are using @scribe-atp/core directly.
Server context
Section titled “Server context”Pass request.signal directly from the incoming request:
// React Router v7export async function loader({ request }: LoaderFunctionArgs) { return fetchSite('alice.bsky.social', 'alice-bsky-social', request.signal);}
// Next.js App Routerexport async function GET(request: Request) { return fetchArticle('alice.bsky.social', params.slug, request.signal);}Client context
Section titled “Client context”Create an AbortController and abort when needed:
// Cancel on component unmount (vanilla JS)const controller = new AbortController();const site = await fetchSite('alice.bsky.social', 'alice-bsky-social', controller.signal);
// Later — component unmounts or user navigates away:controller.abort();In React you can do this inside useEffect:
useEffect(() => { const controller = new AbortController();
fetchSite('alice.bsky.social', 'alice-bsky-social', controller.signal) .then(setSite) .catch((err) => { if (err.name !== 'AbortError') throw err; });
return () => controller.abort();}, []);Handling AbortError
Section titled “Handling AbortError”When a signal fires, the rejected promise contains an AbortError. Always check for it and swallow it — a cancelled request is not an error:
try { const site = await fetchSite(author, siteSlug, controller.signal);} catch (err) { if (err instanceof Error && err.name === 'AbortError') { return; // normal — request was cancelled } throw err; // unexpected error — re-throw}