Dyrected
Model ContentFields

Number

A numeric field for integers and decimals.

The number field stores a numeric value — integers or decimals. Use it for prices, quantities, ratings, ordering weights, and any value you want to store, filter, and sort as a number rather than text.

defineNumberField({ name: 'price', label: 'Price', required: true })

Guiding entry with a range

Number fields accept advisory min and max values. The admin editor uses them to bound the number input, nudging editors toward valid values as they type.

defineNumberField({ name: 'rating', label: 'Rating', min: 1, max: 5 })

Like the text length limits, min and max guide the editing experience but do not reject an out-of-range value on their own. When you need a hard rule — a strict range, rounding, or a computed total — add a hook that runs on write, so it applies on every path and not just the admin form.

Filtering and sorting

If you filter or sort on a number often, mark it promoted so it becomes an indexed column. See Database indexes.

Formatting how the value displays

A raw number reads fine in your database, but 1234.5 is not how you want a price to look in the admin. Set admin.format to tell Dyrected how to present the value in read-only places — list columns and the preview beneath the input — without changing what's stored or how editors type it in.

The quickest form is a shorthand string, which uses sensible defaults:

defineNumberField({ name: 'price', label: 'Price', admin: { format: 'currency' } })

That renders 1234.5 as $1,234.50 in the list view. When you need to configure the format — a specific currency, a star count, fraction digits — pass an object with a type instead:

defineNumberField({
  name: 'price',
  label: 'Price',
  admin: { format: { type: 'currency', currency: 'NGN' } },
})

Formatting is display-only. The stored value stays a plain number, the API returns a plain number, and the editor still types into a normal number input — so filtering, sorting, and your frontend code are all unaffected. Think of it as a lens over the value in the admin, not a transformation of it.

Available formats

Each format works as a shorthand string or as an object when you want to configure it.

FormatExample input → outputNotes
currency1234.5$1,234.50Defaults to USD. Set currency to any ISO 4217 code, e.g. 'NGN', 'EUR'.
percent0.550%Treats the value as a ratio by default. Set scale: false when you store 50 to mean 50%.
decimal1234.51,234.5Grouped number. Set minimumFractionDigits / maximumFractionDigits to fix the decimals.
compact12001.2KAbbreviates large numbers. Good for view counts, reach, follower totals.
bytes15361.5 KBFile sizes. Set binary: true for KiB/MiB (1024-based) units.
unit55 kmRequires a unit, e.g. 'kilometer', 'liter', 'celsius'.
rating4 → ★★★★☆Renders stars instead of text. Defaults to 5 stars; set max to change the count.

A rating is a good example of when to reach for the object form, since you almost always want to set the star count:

defineNumberField({ name: 'score', label: 'Score', admin: { format: { type: 'rating', max: 5 } } })

Every option is a plain string or JSON-serializable object, so formats round-trip through Dyrected Cloud unchanged.

When a format isn't enough

admin.format only changes presentation. If you need the stored value to be rounded, clamped, or derived — a total that must always equal quantity × price, say — that's a job for a hook that runs on write, so the rule holds on every path and not just the admin form.

Generated reference

The contract below is generated from the public @dyrected/core exports by @dyrected/knowledge, so it stays in sync with the package. See Fields for the shared field options every type accepts.

NumberField

A numeric value. Optional advisory min/max guide editors without enforcing server-side validation.

export type NumberField = TypedField<"number", number, NumberFieldAdmin> &
  NumberLimitFieldConfig;

NumberFieldAdmin

Exported type from @dyrected/core.

export type NumberFieldAdmin = NumberLimitFieldAdmin & {
  /** How the value is displayed in read-only Admin surfaces (list cells, read-only inputs). Does not affect storage or editing. */
  format?: NumberFormat;
};

NumberFormat

How a number field's value is presented in read-only Admin surfaces (list cells and read-only inputs). Display only — the stored value is unchanged, and editing still uses a plain numeric input. Every option is JSON-serializable so it round-trips through Dyrected Cloud.

Pass a shorthand string for defaults (format: "currency") or an object to configure it (format: { type: "currency", currency: "NGN" }).

export type NumberFormat =
  /** Shorthand for the matching object form, using that format's defaults. */
  | "decimal"
  | "currency"
  | "percent"
  | "compact"
  | "bytes"
  | "rating"
  /** Grouped number, e.g. `1234.5` → `1,234.5`. */
  | {
      type: "decimal";
      /** BCP 47 locale tag. Defaults to the viewer's browser locale. */
      locale?: string;
      minimumFractionDigits?: number;
      maximumFractionDigits?: number;
    }
  /** Currency amount, e.g. `1234.5` → `$1,234.50`. */
  | {
      type: "currency";
      /** ISO 4217 currency code, e.g. `"USD"`, `"NGN"`, `"EUR"`. Defaults to `"USD"`. */
      currency?: string;
      /** BCP 47 locale tag. Defaults to the viewer's browser locale. */
      locale?: string;
      minimumFractionDigits?: number;
      maximumFractionDigits?: number;
    }
  /**
   * Percentage. By default the stored value is a ratio, so `0.5` → `50%`. Set
   * `scale: false` when the stored value is already a percentage, so `50` → `50%`.
   */
  | {
      type: "percent";
      /** BCP 47 locale tag. Defaults to the viewer's browser locale. */
      locale?: string;
      /** `false` when the stored number is already scaled to 0–100. Defaults to `true`. */
      scale?: boolean;
      minimumFractionDigits?: number;
      maximumFractionDigits?: number;
    }
  /** A measurement unit, e.g. `5` → `5 km` with `unit: "kilometer"`. */
  | {
      type: "unit";
      /** A [sanctioned Intl unit](https://tc39.es/proposal-unified-intl-numberformat/section6/locales-currencies-tz_proposed_out.html#sec-issanctionedsimpleunitidentifier), e.g. `"kilometer"`, `"liter"`, `"celsius"`. */
      unit: string;
      unitDisplay?: "short" | "long" | "narrow";
      /** BCP 47 locale tag. Defaults to the viewer's browser locale. */
      locale?: string;
      maximumFractionDigits?: number;
    }
  /** Abbreviated large numbers, e.g. `1200` → `1.2K`. */
  | {
      type: "compact";
      /** BCP 47 locale tag. Defaults to the viewer's browser locale. */
      locale?: string;
      maximumFractionDigits?: number;
    }
  /** A byte count rendered with units, e.g. `1536` → `1.5 KB`. */
  | {
      type: "bytes";
      /** Use 1024-based units (`KiB`, `MiB`) instead of 1000-based (`KB`, `MB`). Defaults to `false`. */
      binary?: boolean;
      maximumFractionDigits?: number;
    }
  /** A star rating, e.g. `4` → `★★★★☆` with `max: 5`. */
  | {
      type: "rating";
      /** Total number of stars. Defaults to `5`. */
      max?: number;
    };

On this page

Dyrected| Cloud

Get your backend ready in minutes

Use a managed database, storage, APIs, and admin dashboard without setting up the infrastructure yourself.

Set Up My Backend