QUESTPIE
Build Your BackendData Modeling

Localization

Enable multi-language content with per-field localization and locale configuration.

QUESTPIE supports per-field content localization. Mark any field as localized: true and it stores separate values for each configured locale.

Locale Configuration

Define content locales in the locale convention file:

locale.ts
import { locale } from "#questpie/factories";

export default locale({
	locales: [
		{
			code: "en",
			label: "English",
			fallback: true,
			flagCountryCode: "us",
		},
		{ code: "sk", label: "Slovenčina" },
		{ code: "de", label: "Deutsch" },
	],
	defaultLocale: "en",
});
OptionTypeDescription
codestringLocale identifier (e.g., "en", "sk")
labelstringDisplay name
fallbackbooleanFallback locale when translation is missing
flagCountryCodestringISO country code for flag icon
defaultLocalestringDefault locale for new content

Localizing Fields

Chain .localized() on any field:

collections/services.ts
.fields(({ f }) => ({
  name: f.text().required().localized(),
  description: f.textarea().localized(),
  price: f.number().required(),  // NOT localized — same in all locales
}))

Localized fields create separate database columns per locale (e.g., name_en, name_sk) or a JSON structure, depending on the storage strategy.

Localizable Field Types

Most field types support localization:

  • f.text(), f.textarea()
  • f.select()
  • f.array()
  • f.blocks()

Numeric, boolean, date, and relation fields are typically not localized since their values are language-independent.

Labels and Descriptions

Field labels and descriptions also support i18n — but this is for the admin UI language, not content localization:

name: f.text()
  .label({ en: "Full Name", sk: "Celé meno" })
  .description({
    en: "The barber's full display name",
    sk: "Celé zobrazovacie meno holiča",
  })
  .required()
  .localized(),  // Content is also localized

Admin UI Locale

The admin panel has its own locale config for the interface language:

admin-locale.ts
import { adminLocale } from "#questpie/factories";

export default adminLocale({
	locales: ["en", "sk"],
	defaultLocale: "en",
});

This controls the admin interface language, not the content locales.

Querying Localized Content

Server-side

The locale is part of the request context:

// In routes/hooks - locale comes from the request
const services = await collections.services.find({
	where: { isActive: true },
});
// Returns localized `name` and `description` for the current locale

Client-side

Set the locale on the client:

client.setLocale("sk");

const services = await client.collections.services.find({
	where: { isActive: true },
});
// Returns Slovak translations

Localized Arrays

Arrays can be localized as a whole — each locale has its own array:

navigation: f.object({
  label: f.text().required(),
  href: f.text().required(),
}).array().localized(),
  • Fields — Field types and options
  • Globals — Site-wide settings with localization

On this page