Fast Elections can run a ballot in several languages at once — each voter sees the questions, buttons, and emails in a language you offer, with your original wording as the fallback for anything not yet translated.
Choosing languages
On the election editor's Questions step, set the Ballot language — the language your questions are actually written in. Then, on the Languages step that follows, pick one or more Additional ballot languages to offer alongside it. Both are draft-only settings: once you launch, the language list locks along with the questions. Decide your languages before you launch, or you'll be restarting with a new election to add one.
Entering translations
The Languages step shows the translation editor right below the language picker, with one tab per additional language. Each tab shows every string on the ballot — questions, option text, instructions — with a box to translate into that language. Translations save a whole language at a time (moving to another wizard step saves automatically), and a progress counter ("N of M translated") tracks how much of that language is done. There's no requirement to finish before launch — see the launch warning below. After launch, the per-language custom email text stays editable from the election page's Translations button; ballot translations themselves are locked.
What voters see
A voter's ballot opens in their browser's language automatically, if that language is one you're offering; otherwise it opens in the ballot language. A language switcher on the ballot and results pages lets them change it at any time. For any string that hasn't been translated in the language they've picked, Fast Elections quietly falls back to the ballot language rather than showing a blank.
Switching languages on a ballot that's partially filled in clears the selections made so far — option text and IDs don't always line up cleanly across languages, so a language change starts the ballot fresh rather than risk mismatched answers.
Per-voter language
Each voter can also have their own language, independent of what they see when the ballot loads:
- Roster file — add a
languagecolumn (column E) with a code:en,es,fr,pt,de,it,pl,vi,zh-Hans, ortl. Codes are case-insensitive, andzhandfilare accepted as aliases forzh-Hansandtl. - Per-voter Edit dialog, for fixing or setting a language one voter at a time.
- Pasted voters — add a
lang:token anywhere on the line, e.g.maria@example.org, Maria, lang:es. The same codes and aliases as the roster file apply; without a token, pasted voters start on the default (ballot) language.
This per-voter language sets the language their invitation, reminder, and results emails use, and is the language their ballot opens in when their browser doesn't already match one of the offered languages — though they can still switch it with the on-ballot switcher.
The launch warning
If any offered language has untranslated strings, launching shows a warning listing each one — for example "Spanish: 12 of 45 ballot strings untranslated." You'll also see a warning when a language's custom email subject or message was translated before your latest edits to the default text, so an outdated translation can't slip out unnoticed. Neither warning blocks you; you can acknowledge them and launch anyway, and untranslated text falls back to the ballot language for those voters. Translations lock along with the ballot at launch, just like questions, so finish the languages you care about beforehand if you can — anything left undone at launch stays that way for the rest of the election.
AI translations
Typing every language by hand isn't required. A one-time $5 activation per election turns on AI translation, powered by Amazon Translate, and gives that election a pool of 50,000 source characters to spend across every additional language it offers.
On each language's tab, Auto-translate missing fills in only the fields you haven't translated yet, leaving anything you've already entered untouched. Re-translate all overwrites every field in scope — including hand-edited ones — and asks you to confirm first, since that work can't be recovered. Either action deducts source characters (the text being translated from, not the translated result) from the pool; if a translation call fails partway through, the characters for the fields that didn't translate are credited back rather than lost.
For the custom email subject and message there's one extra wrinkle: the app remembers which of those translations the AI wrote and from what text. If you later change the default subject or message, those AI translations count as missing again and get refreshed on the next run — but a subject or message you translated (or edited) by hand is yours, and auto-translate never overwrites it. A Translate email with AI button also sits next to the custom email fields on the launch step (and on the post-launch email card), so you can update every language's email text in one click without visiting each language tab; it lights up only when some language's subject or message is untranslated or out of date.
The same launch freeze described above applies to AI translation, not just manual edits: while the election is still a draft, auto-translate covers ballot fields (title, questions, options) and the custom email fields together; once the election is scheduled or running, it's limited to the custom email fields.
The first time you use auto-translate, a one-time notice reminds you that machine translation can be imperfect — have a fluent speaker review the results before you launch (or before voters see updated email text on a live election). You're still responsible for what the ballot says, the same as with a hand-typed translation.
The pool is shown next to the translation editor as "N of 50,000 characters left." If a language runs the pool dry partway through, activate the add-on again — rebuys stack, so a second $5 activation adds another 50,000 characters on top of whatever's left.