Search pages, headings and code across the docs.

to navigateto open
Dashboard

Account settings

Each user's language, time zone, date and time formats, and smart clipboard.

Every signed-in user has an account page: open the kebab menu in the header and pick "My account", or go to /account. It holds the settings that shape how the dashboard reads for that one user. Nothing here changes the data your app stores, only how the dashboard presents it.

The settings are fields on the Users collection, so they persist with the account and follow the user across devices. Saving applies at once: switch the dashboard language and every label re-renders in place, change the time zone and every date on the page moves with it. No reload.

The settings

SettingDefaultWhat it does
Content languagethe app's default localeThe locale records open in, the same choice the header's switcher makes
Dashboard languagethe app's default languageThe language of the dashboard itself, from your message catalogs
Time zonethe device's zoneThe IANA zone dates and times display and edit in, like Europe/Berlin
Date formatLLThe pattern dates render with
Time formatLTSThe pattern times render with
Smart clipboardoffWatches the clipboard, so a block copied in another tab pastes here
PasswordA new password; left blank, the current one stays

A blank language or time zone means "follow the app" or "follow the device", so a user who never opens the page gets the app's defaults and the device's zone.

Date and time formats

The format settings are token patterns, and a preview beside each input shows the pattern applied to the current moment as you type. YYYY-MM-DD renders 2025-02-24, HH:mm renders 21:30. Any other character passes through, and [...] escapes text that would otherwise read as tokens: [Week] W renders Week 9.

The presets render in the dashboard language. LL reads "February 24, 2025" in English and "24. Februar 2025" in German, LTS reads "9:30:25 PM" and "21:30:25". The defaults are LL and LTS, so a user who sets nothing sees the long localized date and the localized time with seconds.

Date tokens:

TokenMeaning
YYTwo-digit year (e.g. 23)
YYYYFour-digit year (e.g. 2023)
MThe month, beginning at 1 (e.g. 1-12)
MMThe month, 2-digits (e.g. 01-12)
MMMThe abbreviated month name (e.g. Jan-Dec)
MMMMThe full month name (e.g. January-December)
DThe day of the month (e.g. 1-31)
DDThe day of the month, 2-digits (e.g. 01-31)
dThe day of the week, with Sunday as 0 (e.g. 0-6)
ddThe min name of the day of the week (e.g. Su-Sa)
dddThe short name of the day of the week (e.g. Sun-Sat)
ddddThe name of the day of the week (e.g. Sunday-Saturday)
QQuarter (e.g. 1-4)
DoDay of Month with ordinal (e.g. 1st 2nd ... 31st)
wWeek of year (e.g. 1 2 ... 52 53)
wwWeek of year, 2-digits (e.g. 01 02 ... 52 53)
WISO Week of year (e.g. 1 2 ... 52 53)
WWISO Week of year, 2-digits (e.g. 01 02 ... 52 53)
woWeek of year with ordinal (e.g. 1st 2nd ... 52nd 53rd)
LLocalized date, 2-digits (e.g. 02/24/2025)
lLocalized date, 1-digit (e.g. 2/24/2025)
LLLocalized date, long (e.g. February 24, 2025)
llLocalized date, short (e.g. Feb 24, 2025)
[...]Escaped characters (e.g. [Year])

Time tokens:

TokenMeaning
HThe hour (e.g. 0-23)
HHThe hour, 2-digits (e.g. 00-23)
hThe hour, 12-hour clock (e.g. 1-12)
hhThe hour, 12-hour clock, 2-digits (e.g. 01-12)
mThe minute (e.g. 0-59)
mmThe minute, 2-digits (e.g. 00-59)
sThe second (e.g. 0-59)
ssThe second, 2-digits (e.g. 00-59)
SSSThe millisecond, 3-digits (e.g. 000-999)
ZThe offset from UTC, ±HH:mm (e.g. +05:00)
ZZThe offset from UTC, ±HHmm (e.g. +0500)
AAM PM
aam pm
kThe hour, beginning at 1 (e.g. 1-24)
kkThe hour, 2-digits, beginning at 1 (e.g. 01-24)
zAbbreviated named offset (e.g. GMT+1)
zzzUnabbreviated named offset (e.g. Central European Standard Time)
LTLocalized time without seconds (e.g. 8:30 PM)
LTSLocalized time with seconds (e.g. 8:30:25 PM)
[...]Escaped characters (e.g. [Hours])

The same tokens are available to your own dashboard code through formatDatePattern from ohnejs/utils, and formatDateTime, formatDate, formatTime, and formatRelative from ohnejs/dashboard apply the signed-in user's settings for you.

Where the settings apply

  • A dateTime field renders the instant in the date and time formats, in the user's zone, and hovering it shows how long ago that was. A field declared with relativeTime: true swaps the two, and one declared with timezone pins its own zone; see date and time fields.
  • The Updated column of every collection table and the activity feed on the overview show the elapsed time, with the exact instant on hover.
  • A date field renders its calendar day in the date format. A day is not an instant, so the time zone does not apply.
  • A time field renders its clock in the time format; the zone does not apply there either.
  • The calendar pickers open in the user's zone and name their months and days in the dashboard language.

Smart clipboard

Copying a block or a list item in the dashboard puts a small JSON payload on the clipboard. With smart clipboard on, the dashboard reads the clipboard whenever its window gains focus, so a payload copied in another tab or window is ready to paste at once. The browser asks for permission to read the clipboard the first time; denied, the setting has no effect.

Signing out other devices

The footer of the account page holds a button that ends every other session of the account. A phone or a second browser is signed out at its next request, while the current session stays.

Extending the page

An app that adds fields to Users can offer them on the account page. The list of editable fields is the auth:account-fields hook, a filter over the defaults. Return a new list, or change it in place:

ts
// boot/account.ts
import { hook } from 'ohnejs';

hook('auth:account-fields', (fields) => {
  fields.unshift('displayName');
});

The hook fires per request with { user } as its second argument, so the list can differ per user. A name that is not a writable field of Users is ignored, and an empty list hides the page and its menu entry. email and roles are never listed by default: an administrator changes those through the Users collection.

The same list guards PATCH /auth/me, so the form and the endpoint cannot disagree. The endpoints are covered under authentication.