Skip to content
Español

Navigate

Type to search. Press Escape to close.

    Foundations

    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.

    Translation layer: none. Strings: options in your own HTML. Numbers and dates: Intl, following the language of the document.

    Three sources, in order of how often you will touch them:

    1. The served HTML. Labels, headings, options, captions and messages are yours; the package moves them around but never rewrites them.
    2. 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.
    3. 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 is lang on 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.

    ComponentOptionDefaultWhere it shows
    CarouselpauseText, 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
    ComboboxemptyText"No matches"The listbox when nothing matches what was typed
    CommandrecentText, emptyText, placeholder"Recent", "No results", ""Heading of the remembered commands, empty state, and the placeholder of the input
    Countertemplate, overText"", "Too long"The count under a field ({count}, {max}, {remaining}) and what is announced over the limit
    DataTableemptyText, statusText, locale"No rows match", "{visible} of {total} rows", the document languageEmpty state and the live region read after a filter or a sort
    DatepickeropenText, 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
    FormsummaryTitle"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
    LightboxcloseText, 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)
    Pickerplaceholder, searchPlaceholder, emptyText, countText, clearText, removeTextthe 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
    StepperstatusText"Step {index} of {total}: {label}"The live region announced on every step change
    ToastdismissText (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
    Countupgrouping, decimalstrue, -1No 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, activation and 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:

    ComponentOptionDefaultSpanish
    Toast (region)dismissText"Dismiss"data-iv-dismiss-text="Descartar"
    PickerclearText"Clear selection"data-iv-clear-text="Limpiar la selección"
    PickerremoveText"Remove {label}"data-iv-remove-text="Quitar {label}"
    CarouselslideText"{index} of {total}"data-iv-slide-text="{index} de {total}"
    CarouselcounterText"{index} / {total}"data-iv-counter-text="{index} de {total}"
    LightboxcounterText"{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; firstDay exists 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.