Localisation
iVOLT ships no translation layer, no locale files and no runtime dictionary. It writes very little text of its own, and almost all of it is an option you set in the HTML you already serve. Numbers, dates and sorting come from Intl, which reads the language of the document. This page lists the whole surface so a translator can see it at once.
Three sources, in order of how often you will touch them:
- The served HTML. Labels, headings, options, captions and messages are yours; the package moves them around but never rewrites them.
- A
data-iv-*option. The handful of strings the JavaScript generates — an empty state, a status line, the label of a button it creates — are defaults you override per element, or in JavaScript when you initialise the component. Intl. Month and weekday names, the full date a day cell announces, grouped numbers and the collation used when a column is sorted. The locale islangon the closest element that declares it, so<html lang="es">is usually all the configuration there is.
Start with the language of the document
Set lang and everything driven by Intl follows. A Spanish page needs no option at all for dates to read as dates in Spanish:
<html lang="es" class="iv-root" data-iv-theme="system">A region in another language declares it on the region, and the components inside it pick it up:
<section lang="es">
<input class="iv-input" type="date" data-iv-component="datepicker">
</section>Two components accept an explicit override when the visible language and the data language differ: data-iv-locale on the data table (for the collator that sorts) and on the datepicker (for the calendar).
Every generated string
The full list. Everything in this table is an option: put it on the element as data-iv-<option>, or pass it to getOrCreate. Placeholders in braces are replaced by the component and must survive translation.
| Component | Option | Default | Where it shows |
|---|---|---|---|
| Carousel | pauseText, playText, slideText, counterText | "Pause", "Play", "{index} of {total}", "{index} / {total}" | Label of the autoplay button, swapped as it toggles; the accessible name of each slide; the visible position counter, whose digits go through Intl.NumberFormat |
| Combobox | emptyText | "No matches" | The listbox when nothing matches what was typed |
| Command | recentText, emptyText, placeholder | "Recent", "No results", "" | Heading of the remembered commands, empty state, and the placeholder of the input |
| Counter | template, overText | "", "Too long" | The count under a field ({count}, {max}, {remaining}) and what is announced over the limit |
| DataTable | emptyText, statusText, locale | "No rows match", "{visible} of {total} rows", the document language | Empty state and the live region read after a filter or a sort |
| Datepicker | openText, dialogText, prevText, nextText, todayText, clearText, locale, firstDay | "Open calendar", "Choose a date", "Previous month", "Next month", "Today", "Clear" | The toggle, the label of the calendar, its two navigation buttons and its footer. Month names, weekday initials and the full date each day announces come from Intl |
| Form | summaryTitle | "Please fix the following" | Heading of the error summary. The message of each field is the browser's own validationMessage, already in the user's language, unless you serve your own text |
| Lightbox | closeText, prevText, nextText, zoomText, galleryLabel, counterText | "Close", "Previous", "Next", "Zoom", "Image viewer", "{index} / {total}" | The four buttons of the viewer, the accessible name of the dialog, and the position counter (digits through Intl.NumberFormat) |
| Picker | placeholder, searchPlaceholder, emptyText, countText, clearText, removeText | the empty <option> or "Select…", "Search", "No matches", "{count} selected", "Clear selection", "Remove {label}" | The closed control, the search field, the empty state, the summary of a multiple selection, and the accessible names of the clear button and of the remove button on every chip |
| Stepper | statusText | "Step {index} of {total}: {label}" | The live region announced on every step change |
| Toast | dismissText (on the region) | "Dismiss" | Accessible name of the close button of every notice. Title and message come from your call to show() or from the data-iv-message of the trigger |
| Countup | grouping, decimals | true, -1 | No text: the figure is formatted with Intl.NumberFormat in the language of the document, so a Spanish page counts through 1.234,5 |
A Spanish example per component
Real markup, the way a Spanish page would serve it. Only the generated strings appear here: the visible content is authored in Spanish to begin with.
<!-- Carousel -->
<div class="iv-carousel" data-iv-component="carousel" data-iv-autoplay="5000"
data-iv-pause-text="Pausar" data-iv-play-text="Reproducir"
data-iv-slide-text="{index} de {total}" data-iv-counter-text="{index} de {total}">…</div>
<!-- Combobox -->
<div class="iv-combobox" data-iv-component="combobox" data-iv-empty-text="Sin coincidencias">…</div>
<!-- Command palette -->
<dialog class="iv-command" data-iv-component="command" data-iv-recent-text="Recientes"
data-iv-empty-text="Sin resultados" data-iv-placeholder="Escribe un comando…">…</dialog>
<!-- Counter -->
<textarea class="iv-textarea" data-iv-component="counter" data-iv-max="280"
data-iv-template="{remaining} caracteres restantes" data-iv-over-text="Demasiado largo"></textarea>
<!-- Data table -->
<table class="iv-table" data-iv-component="datatable" data-iv-locale="es"
data-iv-empty-text="Ninguna fila coincide"
data-iv-status-text="{visible} de {total} filas">…</table>
<!-- Datepicker -->
<input class="iv-input" type="date" data-iv-component="datepicker"
data-iv-open-text="Abrir el calendario" data-iv-dialog-text="Elige una fecha"
data-iv-prev-text="Mes anterior" data-iv-next-text="Mes siguiente"
data-iv-today-text="Hoy" data-iv-clear-text="Limpiar">
<!-- Form -->
<form class="iv-form" data-iv-component="form" data-iv-summary="true"
data-iv-summary-title="Corrige lo siguiente">…</form>
<!-- Lightbox -->
<div class="iv-gallery" data-iv-component="lightbox" data-iv-gallery-label="Visor de imágenes"
data-iv-close-text="Cerrar" data-iv-prev-text="Anterior" data-iv-next-text="Siguiente"
data-iv-zoom-text="Ampliar" data-iv-counter-text="{index} de {total}">…</div>
<!-- Picker -->
<select class="iv-select" multiple data-iv-component="picker"
data-iv-search-placeholder="Buscar" data-iv-empty-text="Sin coincidencias"
data-iv-count-text="{count} seleccionados"
data-iv-clear-text="Limpiar la selección" data-iv-remove-text="Quitar {label}">
<option value="">Elige un país</option>
</select>
<!-- Toast region -->
<div class="iv-toast-region" id="avisos" data-iv-component="toast"
data-iv-dismiss-text="Descartar"></div>
<!-- Stepper -->
<div class="iv-stepper" data-iv-component="stepper"
data-iv-status-text="Paso {index} de {total}: {label}">…</div>The same in JavaScript, when the markup is produced by a framework and the strings live in your own catalogue:
import { Picker } from "@intervolutions/ivolt/picker";
Picker.getOrCreate(el, {
searchPlaceholder: t("search"),
emptyText: t("noMatches"),
countText: t("nSelected"), // keep the {count} placeholder
});Precedence is defaults < data-iv-* < options in JavaScript, so a per-page default in the markup can still be overridden by the catalogue at initialisation.
Placeholders, and what not to translate
- Keep the braces.
{count},{visible},{total},{index},{label},{max}and{remaining}are replaced verbatim; a translated brace is printed as text. - Word order is free. The replacement is positional only in the sense that every placeholder is substituted wherever it appears, so
"{visible} de {total} filas"is as valid as the English order. - Plurals are yours. The package does not pick a plural form. When one string has to serve one and many, write it so both read well, or set the option from your own catalogue, which does know.
- Option values are not text.
placement,effect,filter,activationand the rest take fixed keywords; translating them disables the option.
Right to left
Set dir="rtl" on the document or on a region. The stylesheets are written with logical properties and the components that have a direction — carousel, drawer, marquee, megamenu, popover, range, and the light and scan effects — mirror themselves; no option is involved. Arrow keys follow the writing direction too. It is tested in all three engines.
Nothing is left hard-coded
Until 0.9 six strings were written by the JavaScript with no option behind them — the close button of a notice, the clear and remove buttons of the picker, the accessible name of a carousel slide and the two position counters. They are options now, so a page can be translated end to end without touching generated markup:
| Component | Option | Default | Spanish |
|---|---|---|---|
| Toast (region) | dismissText | "Dismiss" | data-iv-dismiss-text="Descartar" |
| Picker | clearText | "Clear selection" | data-iv-clear-text="Limpiar la selección" |
| Picker | removeText | "Remove {label}" | data-iv-remove-text="Quitar {label}" |
| Carousel | slideText | "{index} of {total}" | data-iv-slide-text="{index} de {total}" |
| Carousel | counterText | "{index} / {total}" | data-iv-counter-text="{index} de {total}" |
| Lightbox | counterText | "{index} / {total}" | data-iv-counter-text="{index} de {total}" |
The two counters also format their digits with Intl.NumberFormat in the language of the document, so a locale with its own numerals gets them without any further configuration. The × glyph of the dismiss button stays as it is: it is decorative, hidden from assistive technology, and what is announced is dismissText.
Checking a translation
- Open the page with the language set and read the live regions with the developer tools, not only the visible text: the status of the data table and of the stepper are announced, not printed.
- Check the calendar with a locale whose week starts on Monday and one where it starts on Sunday;
firstDayexists for runtimes that do not expose the week information. - Check a long translation in the narrow layout: German and Spanish labels are often half again as long as the English ones, and the buttons of the viewer and the carousel sit in a row.
- Check that a number still reads correctly when the counter animates: the format is chosen once, from the language of the document.