Introducing the FeedbackKit JavaScript SDK
Today we are releasing JavaScript SDK 1.0, the package that connects a web app to FeedbackKit. Where the Swift SDK ships finished SwiftUI screens, the JavaScript SDK is a typed API client: it fetches the project's requests, files new ones, casts and removes votes, and reads and writes comments. The markup and the CSS are yours, so the board looks like the rest of your site.
The short version
- One class,
FeedbackKit, with groups of calls for requests, votes, comments and users:feedback,votes,commentsandusers. - Written in TypeScript and shipped with its type definitions, as ES module and CommonJS builds.
- No runtime dependencies. It uses the platform's
fetch, and runs in current browsers and in Node.js 18 or newer. - Each request shows one of six statuses: Pending, Approved, In Progress, TestFlight, Completed or Rejected.
- Your app can report each user's MRR, so your team can rank requests by the revenue behind them.
- Errors arrive as typed classes, one per kind of failure.
What is in JavaScript SDK 1.0
The client
You create one client with your project's API key and keep it for the life of the page or process. The constructor also takes a baseUrl, a userId and a timeout in milliseconds, which defaults to 30 seconds. Every call sends the key as an X-API-Key header. When a user id is set, it also goes along as X-User-Id, which is how the server knows whether that person has voted on each request. setUserId() changes the id after a sign-in or a sign-out, and getUserId() and getBaseUrl() read the current values.
Requests
feedback.list() returns the project's requests, most votes at the top. It takes an optional status and category to narrow the list, and includeMerged to bring back requests your team has merged into another. feedback.get(id) fetches one request. feedback.create() files a new one with a title, a description, a category and the user's id, plus an optional email for status updates. The categories are Feature Request, Bug Report, Improvement and Other, available as the FeedbackCategory enum, and the statuses are the FeedbackStatus enum.
Votes
votes.vote(id, { userId }) casts a vote and votes.unvote(id, { userId }) removes it. Both answer with the new vote count and whether the user has voted. A vote can carry an email and notifyStatusChange: true, so the voter is told when the request moves on. The server refuses a second vote from the same user, and refuses votes on Completed and Rejected requests.
Comments
comments.list(id) returns a request's comments, oldest at the top, and comments.create(id, { content, userId }) adds one. Each comment says whether it came from your team, so your page can label the replies people are waiting for.
Users and revenue
The SDK does not invent user ids. Your app passes the id it already has, or one it generates and keeps for a signed-out visitor. To weigh requests by revenue, call users.register({ userId, mrr }) with what that user pays per month. Calling it again with a new amount updates it.
Errors
Every failure is a FeedbackKitError with a statusCode and a code, and the common cases have their own subclasses: ValidationError (400), AuthenticationError (401), PaymentRequiredError (402), ForbiddenError (403), NotFoundError (404), ConflictError (409) and NetworkError for a timeout or a dropped connection. A repeat vote is a ConflictError, and a vote on a closed request is a ForbiddenError, so instanceof checks are enough to show the right message.
Getting started
Install the package from npm:
npm install feedbackkit-js
Then create a client with your project's API key, which you find in the FeedbackKit admin app under the project's settings, and fetch the board:
import { FeedbackKit, FeedbackCategory } from 'feedbackkit-js';
const feedbackKit = new FeedbackKit({
apiKey: 'sf_your_api_key',
baseUrl: 'https://feedbackkit.swiftly-workspace.com/api/v1',
userId: 'trailmate_user_4821'
});
const requests = await feedbackKit.feedback.list();
await feedbackKit.feedback.create({
title: 'Offline maps',
description: 'Download a region before a hike so the map works without signal.',
category: FeedbackCategory.FeatureRequest,
userId: 'trailmate_user_4821'
});
A note on installing 1.0. On npm the package is feedbackkit-js, and npm install gives you 1.0.1. It has the same calls as 1.0.0 and changes two things: the type re-exports are declared with export type, and the default baseUrl is the production server. The default in 1.0.0 named a host that does not resolve, which is why the example passes the address. With 1.0.1 you can leave baseUrl out.
One thing to know about the responses
The TypeScript types describe camelCase fields such as voteCount, hasVoted and createdAt. The server answers in snake_case, and 1.0 passes its JSON through unchanged, so at runtime those values sit on vote_count, has_voted and created_at, and the camelCase names read as undefined. Fields of one word, such as id, title, status and category, are the same either way. Until the SDK converts the keys itself, map each response to camelCase before you use it. The JavaScript SDK 1.0 tutorial has a ten-line helper for it, and walks through the rest: a user id for signed-out visitors, the list, voting, the submit form, comments, MRR and testing. The reference is in the JavaScript SDK docs.
How FeedbackKit fits in
The SDK is the part your users touch. Your team works in the FeedbackKit admin app for iPhone, iPad and Mac: read new requests, merge duplicates, reply in the comments, sort by votes or by the MRR behind them, and move a request through Approved, In Progress and TestFlight to Completed. A project's key works from every SDK, so a web app and an iOS app can share one board. When a request's status changes, the person who filed it and left an email can be told by email. On Pro and up, requests can go to GitHub, Linear, Notion, ClickUp or Monday.com, and new ones can be posted to Slack. See pricing for what each plan includes.
Here is how triage looks in FeedbackKit, with sample data from a fictional hiking app:
Where the requests land
What comes next
Later releases each have their own post, beginning with JavaScript SDK 1.1. If you are starting today, the current JavaScript tutorial covers the latest version.
Every plan includes the JavaScript SDK. Start free, create a project, and put the board on your site.