SDK installation
Install @landedso/sdk to collect feedback in your own UI instead of the hosted widget.
Use @landedso/sdk when you want full control over the feedback UI in your app — a custom button, modal, sidebar, or inline form — while still sending submissions to Landed.
This is an alternative to the hosted feedback widget, which loads Landed's iframe UI via script tags.
How it works
Your app installs the npm package and calls Landed's public API with your workspace publishable key (wk_pub_...). The SDK handles authentication, config loading, uploads, and submission payloads.
sequenceDiagram
participant App as Your app
participant SDK as @landedso/sdk
participant API as Landed API
App->>SDK: LandedClient.create({ publishableKey })
App->>SDK: identify({ id, email })
App->>SDK: submit({ text, storageRefIds })
SDK->>API: POST /api/v1/feedback/submissions
API->>API: Create or continue a conversation, append a customer messageSubmissions appear as conversations in the support inbox.
Quick actions
Identify users
Attach signed-in users before they submit feedback.
Client & hooks
API reference for the headless client and React hooks.
Hosted widget
Prefer a drop-in button? Use the script-tag widget instead.
Prerequisites
- Admin access in Landed
- Your workspace publishable key from Settings → Widget (use the Custom UI SDK tab)
- A JavaScript/TypeScript app (React recommended for hooks)
Install
npm install @landedso/sdkHeadless client
import { LandedClient } from "@landedso/sdk";
const landed = LandedClient.create({
publishableKey: "wk_pub_YOUR_KEY",
// Optional — defaults to https://landed.so
baseUrl: "https://landed.so",
});
// Verify Local / Production Setup from the current browser origin.
// Do not set or spoof Origin — browsers send it automatically.
await landed.ping();
// Optional: attach a signed-in user
landed.identify({
id: "user_123",
email: "jane@example.com",
});
// Load widget settings (fields, copy, anonymous allowed)
const config = await landed.getConfig();
// Submit feedback from your custom UI
await landed.submit({
text: "Love the new dashboard",
context: {
pageUrl: window.location.href,
custom: { plan: "pro" },
},
});
// Display published changelog releases in your app
const releases = await landed.listChangelogReleases({ limit: 5 });
const latest = await landed.getChangelogRelease(releases.data[0].id);Verify setup with ping()
After installing the SDK in your product, call landed.ping() once from the real app origin (localhost or production). Landed uses the browser Origin to mark Local setup or Production setup in the dashboard. These checks are informational; they never block your workspace, your trial, or checkout.
- Prefer
ping()over callingPOST /api/v1/pingyourself when using the SDK. - Call it from the browser (or same-origin frontend) so the request carries a real product origin.
- Do not set, spoof, or strip the
Originheader — use browser defaults.
await landed.ping();
// { kind: "production" | "local" | "absent", localSetupAt, productionSetupAt, updated }React hooks
import {
LandedProvider,
useLandedConfig,
useIdentify,
useSubmitFeedback,
} from "@landedso/sdk/react";
function FeedbackForm() {
const { config, isLoading } = useLandedConfig();
const identify = useIdentify();
const { submit, isSubmitting } = useSubmitFeedback();
if (isLoading || !config) return null;
return (
<form
onSubmit={async (event) => {
event.preventDefault();
await submit({ text: "Great product!" });
}}
>
<button type="submit" disabled={isSubmitting}>
{config.widget.copy.submitLabel}
</button>
</form>
);
}
export function App() {
return (
<LandedProvider publishableKey="wk_pub_YOUR_KEY">
<FeedbackForm />
</LandedProvider>
);
}Attachments
Upload files before submitting:
const file = document.querySelector("input[type=file]")!.files![0];
const upload = await landed.upload(file);
await landed.submit({
text: "Bug report with screenshot",
storageRefIds: [upload.storageRefId],
});Verify
- Call
await landed.ping()from your product origin and confirm local or production setup updates in Landed. - Wire up a test form in your app.
- Submit feedback through your custom UI.
- Open Inbox in Landed and confirm the submission appears as a conversation.
Widget vs SDK
| Hosted widget | @landedso/sdk | |
|---|---|---|
| UI | Landed iframe + floating button | Your own components |
| Install | Script tags | npm install @landedso/sdk |
| API | Same public endpoints | Same public endpoints |
| Key | wk_pub_... | wk_pub_... |
Next step
If your users sign in, follow identify users so submissions are attributed correctly.