@handoverhq/sdk
v0.1.7
Published
Secure client SDK for the Handover CMS platform
Readme
@handoverhq/sdk
Official SDK for integrating client sites with the Handover platform API.
Installation
pnpm add @handoverhq/sdkQuick start
import { Handover, HandoverError } from "@handoverhq/sdk";
const handover = new Handover({
apiKey: process.env.NEXT_PUBLIC_HANDOVER_API_KEY!,
url: process.env.NEXT_PUBLIC_HANDOVER_API_URL!,
});
try {
const content = await handover.getContent();
console.log(content.text, content.images);
console.log(content.imagesByKey["hero"].url);
const spanishContent = await handover.getContent({ locale: "es", fallbackLocale: "en" });
console.log(spanishContent.text["homepage.hero.title"], spanishContent.availableLocales);
const posts = await handover.listMarkdownDocuments("blog", { numItems: 10 });
const post = await handover.getMarkdownDocument(posts.page[0].slug);
console.log(post.title, post.html);
const html = await handover.getMarkdownHtml("getting-started");
console.log(html);
await handover.submitContactForm({
senderName: "Ada Lovelace",
senderEmail: "[email protected]",
message: "I'd like to discuss a project.",
fields: { budget: "$5k-$10k" },
});
} catch (error) {
if (error instanceof HandoverError && error.code === "HANDOVER_LOCKED") {
// render lock screen
}
}Security notes
- Use
NEXT_PUBLIC_HANDOVER_API_KEYonly on trusted client projects you manage for your own customers. - Use project-level API keys (
ho_live_*orho_test_*) and rotate them from the Handover dashboard when compromised. - Do not use this SDK in untrusted third-party scripts/extensions where your key can be extracted.
- API key is sent via
X-Handover-Api-Keyheader for write operations and can fallback to query param only for legacy content reads. - Client passwords are never persisted by the SDK; storage decisions are up to your app.
- Localized content uses keys like
i18n.es.homepage.hero.title; callgetContent({ locale: "es" })to overlay translations onto base keys.
Error handling
The SDK throws HandoverError with stable code values:
HANDOVER_LOCKEDINVALID_PASSWORDINVALID_API_KEYAUTH_RATE_LIMITEDSTORAGE_LIMIT_EXCEEDEDINVALID_IMAGE_TYPEINVALID_MARKDOWN_TYPEINVALID_CONFIGURATIONINVALID_RESPONSENETWORK_ERRORREQUEST_FAILED
Use the code property instead of string-matching error.message.
