Skip to content
VoteFirst Docs
Dashboard

Embed

Wording and language

Every word the widgets say is replaceable, and none of it is a translation file you have to keep in step with ours. Pass the strings you want in the language you want them in.

The text option

text merges over the widgets' own wording. Name only the keys you are changing; everything you leave out keeps its default, so a new key added in a later release arrives in English rather than as an empty label.

German, and only the words that appear
VoteFirst.init({
  project: 'your-project-slug',
  key: 'your-embed-key',
  locale: 'de-DE',
  text: {
    vote: 'Abstimmen',
    voted: 'Abgestimmt',
    votes: 'Stimmen',
    more: 'Mehr anzeigen',
    empty: 'Noch nichts hier',
    suggestTitle: 'Feature vorschlagen'
  }
});

Three of the strings carry a placeholder, which is replaced wherever you put it: {n} is a count of voters, {pct} is a whole number percentage, and {field} is the name of the field a form is complaining about.

Dates and numbers

locale takes a BCP 47 tag and decides how a release date and a vote count are written. Left out, both follow the reader's own browser, which is usually what you want on a public page and not what you want on a page that is only ever in one language.

VoteFirst.init({ project: '...', key: '...', locale: 'de-DE' });
// 17. Aug. 2026, and 1.204 rather than 1,204

A tag the reader's browser does not know falls back to a plain date rather than failing, so an unusual one costs nothing.

Every key

Grouped by where they appear. Anything not listed here is not a string the widgets say.

Shared

KeyDefault
loadingLoading
emptyNothing here yet
retryTry again
errorGenericSomething went wrong
moreShow more
cancelCancel
closeClose
poweredByPowered by VoteFirst

Cards and vote controls

KeyDefault
voteVote
votedVoted
votesvotes
commentcomment, used when there is one
commentscomments
viewsViews
shareOfVoters{pct}% of voters, on the Most Wanted list
developerResponseDeveloper response, above the answer the project owner wrote
denialReasonDenial reason, the same block on a declined feature
votingClosedVoting is closed here, which is what a vote button or a badge says when the column takes no votes and the count is hidden as well

Changelog

The two vocabularies below both reach this field. Releases filed before the newer names existed still carry the older pair, and rows of both kinds sit in the same project, so both are named here.

KeyDefault
featuredFeatured
requestedByRequested by {n} voters
type_newNew
type_featureNew Feature
type_improvementImprovement
type_fixFix
type_bug_fixBug Fix
type_securitySecurity
type_breaking_changeBreaking Change

The request a card opens

Clicking a card opens that request in place of the board, with its counts, its progress and its thread. These are the words that view adds.

KeyDefault
backBack, on the control that returns to the board
upvotesUpvotes
progressProgress

The comment thread

KeyDefault
commentsTitleComments
commentOneComment, used as the heading when there is one
commentNoneNo comments yet
commentHintAdd a comment...
commentSubmitPost Comment
sortNewest, sortOldest, sortTopNewest, Oldest, Top
likeLike
replyReply
replyHintWrite a reply
replySubmitReply, on the button that sends one
removeDelete, on a comment this visitor left
youYou, beside this visitor's own name
anonymousAnonymous, for a comment whose author has no name
roleOwner, roleEditorOwner, Editor, on a comment from your own team

What a refusal says

A refused call is written for the visitor rather than for you. The server's own sentence names routes and headers and never reaches the page; this is what does. The console still gets the real one, and the error object carries the code your handler should branch on.

KeyDefault, and the code behind it
errorRefusedThat is not allowed here. not_allowed
errorBannedYou cannot post on this board. voter_banned
errorBusyToo many requests just now. Try again in a moment. rate_limited
errorGoneThat is no longer here. not_found
errorDoneThat has already been done. already_exists
errorSendingStill sending. Give it a moment. idempotency_in_progress
errorSetupThis is not set up correctly. A wrong key, a project slug that names nothing, or an origin your allowlist does not carry, which are your mistakes rather than the visitor's
tooLong{field} is too long. Shorten it and try again.

The two popups

Every key below exists twice, once with each prefix, so the suggestion form and the problem report form can say different things. Where the default is empty the line is not drawn at all until you give it something.

KeyDefault
suggestTitleSuggest a Feature
suggestIntroEmpty
suggestHeadingTitle
suggestHeadingHintA short, descriptive title
suggestDescriptionDescription
suggestDescriptionHintDescribe the feature you'd like to see...
suggestSubmitSubmit
suggestDoneThanks. Your suggestion has been recorded.
suggestHeldForReviewShown instead of nothing when the project reviews new submissions before they appear
reportTitleReport a problem
reportIntroEmpty
reportHeadingWhat happened
reportHeadingHintA short, descriptive title
reportDescriptionSteps, and what you expected instead
reportDescriptionHintWhat you did, what happened, and what you expected instead
reportSubmitSubmit
reportDoneThanks. Your report has been recorded.
reportHeldForReviewThe same sentence as above, in the report's own noun
suggestClosedThis project is not accepting suggestions right now. A popup has no button to withhold, so a project that takes neither is telling rather than refusing
reportClosedThis project is not accepting reports right now.

The same wording can be given to one popup instead of to every widget, which is what you want when two buttons on the same page open the same form for different reasons.

One form, its own words
VoteFirst.suggest({
  trigger: '#suggest-btn',
  title: 'Tell us what to build',
  intro: 'We read all of these.',
  headingLabel: 'In one line',
  headingHint: 'Dark mode',
  descriptionLabel: 'Why it would help',
  descriptionHint: 'What you are doing when you need it',
  submitLabel: 'Send it',
  doneMessage: 'Got it. Thank you.'
});
OptionReplaces
titlesuggestTitle or reportTitle
introsuggestIntro or reportIntro
headingLabel, headingHintThe first field's label and placeholder
descriptionLabel, descriptionHintThe second field's label and placeholder
submitLabelsuggestSubmit or reportSubmit
doneMessagesuggestDone or reportDone