Localization / L18n in SeaTable
The goal is to create SeaTable apps that are consistently in a single language — not just the SeaTable user interface but also table and column names, as well as select values — while using the same database. Since table, column, and select field labels are static in SeaTable (and most database builders), my approach involves transforming machine names from master tables into corresponding language-specific tables using a two-way sync with Python scripts. This ensures both the master data and all translations are persisted and kept in sync.
This is a conceptual overview, and no scripts have been implemented yet.
Translations Table: l18n
The l18n table serves as a central repository for all translations:
-
The key is the machine-readable name of a table, column, or select value (stored in the
mastercolumn). -
Each language has its own value column to hold translations of the master.
-
To reduce manual input errors, translations are organized using nested records and then flattened with formulas for easier script consumption.
-
A
levelcolumn tells whether a record is a table name (first level), column name (second level), or select value name (third level).
This table provides:
-
Static translations for table, column, and select value names.
-
Lookup functionality for scripts to retrieve translations programmatically.
Master Table: participants
To demonstrate the approach, I’ve used an example master table named participants.
Structure
-
A
namecolumn (text format) is not translated because it needs to remain editable in each language-specific app. Updates to this column are synced across all tables. -
A
categorycolumn (select format) requires translations for values likepupilandteacher.
Auxiliary Fields
sync_status,sync_source, andlast_updatedcolumns provide metadata to:
-
Avoid synchronization loops.
-
Facilitate debugging and error tracking.
Formulas are not suitable for the name column because users in language-specific apps must be able to edit the text field, with changes propagated to all other tables.
Language-Specific Tables: E.g., Teilnehmer
Each language-specific table mirrors the structure of the master table but includes localized static labels:
-
A
mastercolumn links the language-specific record to the corresponding master record. -
The
namecolumn (translated toName) allows user edits. -
The
categorycolumn (translated toKategorie) provides translated select values (e.g.,SchülerforpupilandLehrerforteacher).
An app for German users would use this table as its backend. Any user action—creating a new record or updating an existing one—triggers the generic sync_lang_to_master Python script.
sync_lang_to_master Script
The sync_lang_to_master script:
-
Detects the current language from the
context. -
Writes data to the master table.
-
Uses the
l18ntable to match translated select values to their corresponding entries in the master table.
sync_master_to_langs Script
When the master table is updated (e.g., a new row or an update to an existing row), an automation triggers the sync_master_to_langs script. This script:
-
Propagates the updates to all language-specific tables.
-
Ensures data consistency across all translations.
Thoughts?
Are there better solutions?
The ideal solution would be a new SeaTable feature that natively supports localization. This feature would allow users to:
-
Add translations for tables, columns, and select fields directly in the UI.
-
Dynamically render translations based on the app’s selected language (defaulting to the user’s SeaTable language).
Such a feature would eliminate the need for workarounds and provide a modern, streamlined approach to localization.


