demo D219
Locales, and it mirrors in htmx
The same grid in English, Japanese and Arabic, which sets the grid right to left
locale · direction: 'rtl'
This shows the same grid in English, Japanese and Arabic, with Arabic laying the whole grid out right to left. It proves the grid adapts to a locale end to end, mirroring its layout for right-to-left languages rather than just swapping words.
This is the htmx version. A server-rendered table is upgraded in place, so the page is readable before any script runs and gains the full grid when the module loads, which suits a progressively enhanced app.
The configuration
<link rel="stylesheet" href="https://cdn.latticegrid.dev/lattice-grid@1.108.0/lattice-grid.min.css">
<script type="importmap">
{ "imports": { "@toclocoinc/lattice-grid": "https://cdn.latticegrid.dev/lattice-grid@1.108.0/lattice-grid.esm.min.js" } }
</script>
<div id="buttons" style="display: flex; gap: 8px; margin-bottom: 12px"></div>
<!-- A real, server-rendered table: readable with JavaScript off. data-field on
each header names the column that cell becomes, and data-id on each row is
the key the grid carries it under. -->
<table id="locales-and-rtl-table" data-lattice-grid>
<thead>
<tr>
<th data-field="product">Product</th>
<th data-field="price">Price</th>
<th data-field="updated">Updated</th>
<th data-field="share">Share</th>
</tr>
</thead>
<tbody>
<tr data-id="1"><td>Desk lamp</td><td>42.5</td><td>2026-08-01</td><td>0.18</td></tr>
<tr data-id="2"><td>Task chair</td><td>189</td><td>2026-08-03</td><td>0.41</td></tr>
<tr data-id="3"><td>Monitor arm</td><td>76.25</td><td>2026-08-09</td><td>0.27</td></tr>
<!-- the rest of the rows, rendered by your server -->
</tbody>
</table>
<script type="module">
import { hydrateTable, registerLocale } from 'https://cdn.latticegrid.dev/lattice-grid@1.108.0/modules/htmx.esm.min.js';
import { JA_JP } from 'https://cdn.latticegrid.dev/lattice-grid@1.108.0/locales/ja-JP.esm.min.js';
import { AR } from 'https://cdn.latticegrid.dev/lattice-grid@1.108.0/locales/ar.esm.min.js';
// This module carries its own copy of the grid, which a locale file's own
// registration does not reach: hand the module the catalogue.
registerLocale('ja-JP', JA_JP);
registerLocale('ar', AR);
// The same grid and the same rows in three locales. Only the chrome and the
// formatting change: numbers, currency and dates read the grid's locale, and
// Arabic sets direction: 'rtl', which mirrors the whole grid, pin and all.
const locales = {
English: { locale: 'en-GB', direction: 'ltr', currency: 'GBP', titles: ['Product', 'Price', 'Updated', 'Share'] },
日本語: { locale: 'ja-JP', direction: 'ltr', currency: 'JPY', titles: ['製品', '価格', '更新日', 'シェア'] },
العربية: { locale: 'ar-EG', direction: 'rtl', currency: 'EGP', titles: ['المنتج', 'السعر', 'تاريخ التحديث', 'الحصة'] },
};
let grid;
function build(name) {
const L = locales[name];
grid?.destroy();
grid = hydrateTable(document.getElementById('locales-and-rtl-table'), {
locale: L.locale,
direction: L.direction,
columns: [
{ field: 'product', title: L.titles[0], layout: { pin: 'start', width: 180 } },
{ field: 'price', title: L.titles[1], type: 'number',
format: { style: 'currency', currency: L.currency }, total: 'sum' },
{ field: 'updated', title: L.titles[2], type: 'date' },
{ field: 'share', title: L.titles[3], type: 'number', format: { style: 'percent' } },
],
});
}
for (const name of Object.keys(locales)) {
const b = document.createElement('button');
b.textContent = name;
b.onclick = () => build(name);
document.getElementById('buttons').append(b);
}
build('English');
</script>