SDK guides
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, publicationUrl, signal?)
fetchArticle(author, articleSlug, signal?)
When you need this
In server contexts, passing the request's signal ensures the 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
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
Pass request.signal directly from the incoming request:
// React Router v7/v8
export async function loader({ request }: LoaderFunctionArgs) {
return fetchSite('alice.bsky.social', 'https://alice.bsky.social', request.signal);
}
// Next.js App Router
export async function GET(request: Request) {
return fetchArticle('alice.bsky.social', params.slug, request.signal);
}
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', 'https://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', 'https://alice.bsky.social', controller.signal)
.then(setSite)
.catch((err) => {
if (err.name !== 'AbortError') throw err;
});
return () => controller.abort();
}, []);
Note
Use @scribe-atp/react instead of writing this by hand — useSite and useArticle handle the AbortController lifecycle for you.
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, publicationUrl, controller.signal);
} catch (err) {
if (err instanceof Error && err.name === 'AbortError') {
return; // normal — request was cancelled
}
throw err; // unexpected error — re-throw
}