Text formatting
The format field on a column produces locale-aware formatted strings
without you writing a renderer.
Open the live example: Finances - ledger (Industry Templates)
Number
{ field: 'count', header: 'Count',
format: { type: 'number', options: { maximumFractionDigits: 0 } } }
options is Intl.NumberFormatOptions. Combine with locales for
non-default locales:
{ field: 'count', header: 'Anzahl',
format: { type: 'number', locales: 'de-DE', options: { maximumFractionDigits: 0 } } }
Currency
{ field: 'salary', header: 'Salary',
format: { type: 'currency', currency: 'USD' } }
currency is an ISO 4217 code; if omitted, USD is used.
Percent
// values are fractions (0.42 → 42%)
{ field: 'utilization', header: 'Util',
format: { type: 'percent' } }
// values are 0–100 (42 → 42%)
{ field: 'progress', header: 'Progress',
format: { type: 'percent', valueIsPercentPoints: true } }
Date / datetime
{ field: 'joinedAt', header: 'Joined',
format: { type: 'date', pattern: 'y-m-d' } }
{ field: 'updatedAt', header: 'Updated',
format: { type: 'datetime', pattern: 'medium' } }
Built-in patterns:
| pattern | shorthand for |
|---|---|
'd' |
short numeric date |
'D' |
long date |
'y-m-d' |
year-month-day |
'short' | 'medium' | 'long' |
dateStyle / timeStyle presets |
Combine pattern with options to override individual fields.
Custom formatter
For anything format cannot express, use formatter:
{
field: 'temperature',
header: 'Temp',
formatter: ({ value }) => `${Number(value).toFixed(1)}°C`,
}
formatter runs after the accessor and before the cell renderer.
Its return value is what gets displayed and copied to the clipboard.
Order of precedence
When a column has both, the resolution order is:
field/fieldFnproduces the value- If
cellis set, it renders -format/formatterare ignored - Otherwise
formatterruns if set - Otherwise
formatruns if set - Otherwise the value is rendered as
String(value)
formatter vs format
format is the declarative, locale-aware path and should be the default.
formatter is the escape hatch for a one-off shape Intl has no opinion about -
and it runs after the accessor, so it sees the value the column resolved.
<script lang="ts">
import { SvGrid, renderSnippet, type GridColumns } from '@svgrid/grid'
type Person = {
id: number
name: string
department: string
city: string
age: number
salary: number
joined: string
active: boolean
}
const people: Person[] = [
{ id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000, joined: '2021-03-01', active: true },
{ id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000, joined: '2019-07-15', active: true },
{ id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000, joined: '2020-01-20', active: false },
{ id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000, joined: '2022-09-05', active: true },
]
const columns: GridColumns<Person> = [
{ field: 'name', header: 'Name', width: 180 },
// Declarative: Intl does the work and follows the locale.
{ field: 'salary', header: 'Salary', width: 140,
format: { type: 'currency', currency: 'USD' } },
// Bespoke: a compact form Intl will not produce for you.
{ field: 'age', header: 'Tenure', width: 130,
formatter: (ctx) => Number(ctx.value) + ' yrs' },
]
</script>
<SvGrid data={people} {columns} />
Formatting a date string
Dates that arrive as strings are the common case. cellDataType: 'dateString'
tells the grid what it is holding, so sorting and filtering treat it as a date
rather than as text.
<script lang="ts">
import { SvGrid, renderSnippet, type GridColumns } from '@svgrid/grid'
type Person = {
id: number
name: string
department: string
city: string
age: number
salary: number
joined: string
active: boolean
}
const people: Person[] = [
{ id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000, joined: '2021-03-01', active: true },
{ id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000, joined: '2019-07-15', active: true },
{ id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000, joined: '2020-01-20', active: false },
{ id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000, joined: '2022-09-05', active: true },
]
const columns: GridColumns<Person> = [
{ field: 'name', header: 'Name', width: 190 },
{ field: 'joined', header: 'Joined', width: 150,
cellDataType: 'dateString',
format: { type: 'date', options: { dateStyle: 'medium' } } },
]
</script>
<SvGrid data={people} {columns} sortable filterable />
See also
- Cell components - when
formatis not enough. cell-formatting.ts
Related articles
- A Right-Click Context Menu for Your Svelte Data Grid - Build a right-click context menu that wires row actions, handles multi-row selection, and stays out of the way of SvGrid's own event handling.
- A Date-Picker Cell Editor in SvGrid - How to make date columns editable with a real date picker in SvGrid - including display formatting, time zone handling, and validation that preserves user input.
- Conditional Row Styling in SvGrid - Drive row-level background tints, classes, and styles from your data - overdue invoices, failed jobs, VIP records - without touching the DOM directly.