Skip to content
VoteFirst Docs
Dashboard

Embed

Options and events

What you pass to the script when it starts, what you pass to a widget, and what the widget tells you back.

Starting the script

VoteFirst.init runs once per page and takes everything that is true of every widget on it. Only the first two are needed.

OptionWhat it does
projectYour project slug, which is the name in the address of your board.
keyYour embed key. Public by design, and the only credential that belongs in a page.
ssoTokenA token your server signed, if this visitor is already signed in to your product. The same thing as calling client.signIn, one line earlier.
themeauto, which follows your page's own color-scheme, or light or dark. Appearance has the rest.
appearanceColour and spacing overrides for every widget on the page. false takes the board's colours off entirely.
textYour own wording, in place of any of the widgets' own. Wording and language lists every key.
localeA BCP 47 tag such as de-DE, used for dates and vote counts. Left out, they follow the reader's browser.
apiBaseWhere the script sends its requests. It defaults to wherever the script tag itself was loaded from, which is right unless you are proxying. Loaded through a bundler there is no script tag to read, so it falls back to https://app.votefirst.app and says so in the console; name it yourself if you host or proxy VoteFirst.

An option the script does not know is ignored rather than refused, so a misspelled name fails quietly rather than loudly. Calling init again changes only the values you pass again.

Widget options

Every option is optional, and a widget sent one it does not read ignores it. The defaults below are what each widget asks for when you say nothing.

OptionWhat it does
boardThe board slug. VoteFirst.roadmap defaults to roadmap. On the Most Wanted list, naming a board ranks that one board instead of every suggestion in the project.
sortboard, which is the order you arranged and what a board draws by default, or top, votes, trending, new, oldest, comments. top follows the project's own score, which is the weighted total where weighting is on; votes is the plain headcount. The flat feature list defaults to top. The Most Wanted list and the changelog have an order of their own and ignore it.
limitHow many items to load at a time. 20 per column on a board, 10 on the flat list and the Most Wanted list, 5 on the changelog.
featureThe feature id the vote button and the badge draw. Left out, or set to first, both draw whichever feature has the most votes at the moment the page loads.
tagsTag ids to filter by.
searchA search term applied to headings and descriptions.
statusColumn status to filter by: open, planned, in_progress, done, denied or archived. Read by the flat feature list, and by the Most Wanted list, which defaults to open. A board draws the columns the board has.
columnsBoards only. Which columns to draw, named by their status or by their id, for a page with room for two of them rather than five. They keep the board's own order whatever order you list them in.
detailBoards and the flat feature list. false stops a card opening the request, for a page that would rather send a reader to your own address for it.
htmlThe changelog only. false renders each release note as plain text instead of as the markup the server produced from its markdown.
theme, appearanceThe same two as above, for this widget alone.
Two columns of a board, ten cards each
VoteFirst.board('#roadmap', {
  board: 'roadmap',
  columns: ['open', 'in_progress'],
  limit: 10
});

The suggestion and problem report popups take options only, because they have nothing to render into until they open. The wording they use is on Wording and language; these are the rest.

OptionWhat it does
triggerA selector or an element that opens the popup. A selector matching several elements binds all of them.
opentrue opens it as soon as the call runs, for a page whose whole purpose is the form.
containerWhere the dialog is appended. It goes to the end of the document by default, which is what keeps it clear of your own stacking contexts.
heading, descriptionValues the two fields open with, for a report button that already knows what it is about.
contextThe problem report popup only. false stops it sending the page address and the browser with the report.
closeOnDonefalse leaves the thank you on screen instead of closing the dialog two and a half seconds after it is submitted.
A report button that knows which page it is on
VoteFirst.report({
  trigger: '#report-btn',
  heading: 'Problem on the billing page'
});

Events

Listen on one widget through the handle it returns, or on every widget at once with VoteFirst.on. A widget's own listeners run first, then the same event reaches the global bus, so analytics can be hooked once rather than per widget. A listener that throws is reported to the console and does not stop the others.

EventWhen it fires, and what it carries
readyOnce, just after init. Registering a listener after calling init still catches it. Carries project and version.
renderA widget finished drawing, including after a refresh. Carries widget and the element it drew into.
errorA widget could not load, a submission failed, or a sign in was refused. Carries widget and error. The widget shows a retry button of its own.
voteA vote control was used. Carries the feature, hasVoted for whether the visitor now has a vote on it, and the whole result.
identityThe visitor signed in, or was given an anonymous identity. Carries the identity itself.
open, submit, closeA popup opened, sent something, or closed. submit carries the feature that was filed.
Reporting a vote to your own analytics
VoteFirst.on('vote', function (event) {
  analytics.track('roadmap vote', { feature: event.feature.heading });
});

Errors

Everything the script rejects with is an Error with three things added, so a handler can branch on the code and show the message.

VoteFirst.client.vote(1234).catch(function (error) {
  if (error.code === 'already_exists') return;
  console.error(error.status, error.code, error.message);
});
PropertyWhat it carries
codeThe stable half, and the only half worth branching on. The API error codes are the same set.
messageWritten for a person, and liable to change.
statusThe HTTP status, or 0 if the request never reached the server.
fieldThe field at fault when the code is validation_failed, and null otherwise.

An error event carries the same object, so the two ways of finding out are the one thing to handle.

Three codes come from the script rather than from the server. not_configured means init has not run with a project and a key. network means the request never left, which is a reader offline or an extension blocking it. And http_404 and its like appear when a response carried a status but no body to read a code from.