Home/Getting Started/Global Configuration
Getting Started

Global Configuration

provideGridDefaults() sets what every grid in the app starts from, so a grid you add later is already dressed like the rest. A per-grid config still wins — key by key, so overriding one option keeps every other one.

What this site's own defaults look like

This grid sets no rowHeight and no pageSize. Both come from the provideGridDefaults() call in the demo's application config — the same one every other grid on the site inherits.

#
Name
Department
Salary
Status
1
Nadia Haddad
Engineering
8000
Inactive
2
Ben Okafor
Design
11700
Active
3
Yara Nasser
Product
15400
Active
4
Karim Farouk
Support
10100
Active
5
Elena Novak
Finance
13800
Active
6
Walid Haddad
Marketing
8500
Active
7
Alice Okafor
Engineering
12200
Active
8
Petra Nasser
Design
15900
Inactive
9
Idris Farouk
Product
10600
Active
10
Tara Novak
Support
14300
Active
11
Carla Haddad
Finance
9000
Active
12
Omar Okafor
Marketing
12700
Active
13
Nadia Nasser
Engineering
16400
Active
14
Ben Farouk
Design
11100
Active
15
Yara Novak
Product
14800
Inactive
16
Karim Haddad
Support
9500
Active
17
Elena Okafor
Finance
13200
Active
18
Walid Nasser
Marketing
16900
Active
19
Alice Farouk
Engineering
11600
Active
20
Petra Novak
Design
15300
Active
21
Idris Haddad
Product
10000
Active
22
Tara Okafor
Support
13700
Inactive
23
Carla Nasser
Finance
8400
Active
24
Omar Farouk
Marketing
12100
Active
25
Nadia Novak
Engineering
15800
Active
1–50 of 60

This grid's config is three lines, and none of them is about height or paging:

config = { height: 420, scrollMode: 'paging', sortMode: 'client' };

Its rows are 48px tall and it pages at 50, both from the provideGridDefaults() call in this demo's own application config. Every other grid on this site is reading the same two values — which is the point of setting them once: a grid you add next month is already dressed like the rest, without anybody remembering to dress it.

Defaults are a floor, not a lock. Anything you set on a grid still wins, which is the second example. The reverse holds too: a key you never set anywhere falls through to the library's own default, so provideGridDefaults() is somewhere to put the handful of decisions your product has actually made, and nothing more.

A per-grid config wins — one key at a time

The same grid with one line added: rowHeight: 32. The rows are shorter and nothing else moved — the page size is still the app-wide 50, because the merge is per key rather than all-or-nothing.

#
Name
Department
Salary
Status
1
Nadia Haddad
Engineering
8000
Inactive
2
Ben Okafor
Design
11700
Active
3
Yara Nasser
Product
15400
Active
4
Karim Farouk
Support
10100
Active
5
Elena Novak
Finance
13800
Active
6
Walid Haddad
Marketing
8500
Active
7
Alice Okafor
Engineering
12200
Active
8
Petra Nasser
Design
15900
Inactive
9
Idris Farouk
Product
10600
Active
10
Tara Novak
Support
14300
Active
11
Carla Haddad
Finance
9000
Active
12
Omar Okafor
Marketing
12700
Active
13
Nadia Nasser
Engineering
16400
Active
14
Ben Farouk
Design
11100
Active
15
Yara Novak
Product
14800
Inactive
16
Karim Haddad
Support
9500
Active
17
Elena Okafor
Finance
13200
Active
18
Walid Nasser
Marketing
16900
Active
19
Alice Farouk
Engineering
11600
Active
20
Petra Novak
Design
15300
Active
21
Idris Haddad
Product
10000
Active
22
Tara Okafor
Support
13700
Inactive
23
Carla Nasser
Finance
8400
Active
24
Omar Farouk
Marketing
12100
Active
25
Nadia Novak
Engineering
15800
Active
26
Ben Haddad
Design
10500
Active
27
Yara Okafor
Product
14200
Active
28
Karim Nasser
Support
8900
Active
29
Elena Farouk
Finance
12600
Inactive
1–50 of 60

The same three lines, plus one:

config = { height: 420, scrollMode: 'paging', sortMode: 'client',
           rowHeight: 32 };

The rows are shorter, and nothing else changed. Look at the pager under each grid: both report the same number of pages, because both are still using the app-wide pageSize: 50. That is what "merged key by key" means — overriding one option is not opting out of the rest.

The same rule holds one level further in. config.messages merges key by key against the app-wide messages rather than replacing them, so a grid that renames a single string keeps every other translation. See Localisation.

provideGridDefaults()

Call once in ApplicationConfig.providers. Every <gridcraft> in the app inherits these values. Per-grid [config] always takes precedence.

It accepts any GridConfig option — all 61 of them. But they do not all combine with a grid's own [config] in the same way, and the difference is worth knowing before you rely on it.

How a global value combines with a per-grid one

Three behaviours, and every option falls into exactly one of them.

1 · Combined option by option — messages and icons

These two combine key by key. Set the loading text globally and the empty text on one grid, and that grid shows both. Only the keys you repeat get overridden.

provideGridDefaults({ messages: { loading: 'Loading...', empty: 'Nothing here' } })

// This grid gets its own empty text and KEEPS the global loading text.
config = { messages: { empty: 'No employees match' } };

2 · Changeable while the app runs — dir, theme, messages

These three can also be swapped after the app has started, through GridDirectionService below — for a language switcher or a dark-mode toggle. A grid that sets the option itself keeps its own value and ignores the switch.

3 · Replaced completely — every other option

For the rest, a grid that sets the option at all replaces the global value entirely. For a plain value like rowHeight that is exactly what you would expect. For an option that holds a group of settings, it is the part that catches people out:

provideGridDefaults({
  rowSelection: { mode: 'multi', checkboxColumn: false },
})

// This grid meant to change nothing but the mode - but the whole group is
// replaced, so checkboxColumn: false is gone and the checkbox column is back.
config = { rowSelection: { mode: 'single' } };

// Repeat what you want to keep:
config = { rowSelection: { mode: 'single', checkboxColumn: false } };

Only messages and icons combine option by option. For everything else, a grid that sets a group of settings has to repeat the ones it wants to keep from the global value — nothing warns you if it does not.

GridDirectionService

A root-level signal service. Calling setDir('rtl') and setMessages({ records: 'سجل', loading: '...' }) updates all grids that don't have an explicit per-grid override — no page refresh needed.

Whenever your app's active language changes — whether driven by a signal, a service, a URL parameter, or any other mechanism — call setDir() and setMessages() together. All grids update in the same tick. Click the button above to see it live.

effect(() => {
  const l = lang();
  gridLocale.setDir(RTL_LOCALES.has(l) ? 'rtl' : 'ltr');
  gridLocale.setMessages(GRID_MESSAGES[l] ?? GRID_MESSAGES['en']);
});

Priority (highest wins)

  1. Per-grid [config]="{ dir: 'rtl' }" — explicit override for one grid
  2. GridDirectionService.setDir() — reactive app-level direction
  3. provideGridDefaults({ dir: '...' }) — static app-level default
  4. 'ltr' — built-in fallback

The same three levels apply to theme. Set a house theme once with provideGridDefaults, switch it at runtime with GridDirectionService.setTheme() for a dark-mode toggle, and let any single grid pin its own theme with config.theme.

Global configuration API

PropertyTypeDefaultDescription
provideGridDefaults()Partial<GridConfig>—Set once in ApplicationConfig.providers — every grid inherits these defaults; per-grid [config] always wins.
GridDirectionService.setDir()(dir: 'ltr' | 'rtl') => void—Reactive app-level direction — updates every grid without an explicit per-grid override, no refresh.
GridDirectionService.setMessages()(messages: GridMessages) => void—Swap the built-in UI strings at runtime, in the same tick as the direction change.
GridDirectionService.setTheme()(theme: GridTheme) => void—Switch the theme for every grid at runtime — a grid with its own config.theme keeps it.
config.messagesPartial<GridMessages>—Combined option by option with the global value — override one label without repeating the rest.
config.iconsPartial<GridIconSet>—Combined option by option with the global value, the same way messages is. See Custom Icons.
GRID_MESSAGESRecord<string, GridMessages>—Shipped locale packs: en, ar, fr, de, es, pt, fa, ur, tr, zh, ja, ru.
RTL_LOCALESSet<string>—Locale codes the library treats as right-to-left.
config.dir'ltr' | 'rtl''ltr'Explicit per-grid direction — highest priority, beats the service and the global default.