Skip to content

Common adapter options

These are the configuration options that are common across adapters. The adapter-specific options are discussed in the adapter’s page.

These are the properties of the object when you specify adapters to the main configuration.

Example:

// ...
main: svelte({
sourceLocale: 'es',
}),
// ...

type: string default: (first locale in locales in top-level)

This is the language you use in the source code and will not need to be translated. In most cases this will be English.

type: {adapterLoaders} | "custom" default: (depends on the adapter)

This option controls sets the loader to import the runtime from (by the transformed files).

It can be one of the supported loader names by the adapter, in which case the corresponding loader will be generated at startup. For example, for the Svelte adapter, the svelte loader can be used which exports a reactive way to get the runtimes.

Or it can be custom if taking control of the loader file is desired. If using this, the loader files will not be overwritten. When using this, you can use the loader file naming convention (client and server):

{localesDir}/{adapterKey}.loader.{ext}
{localesDir}/{adapterKey}.loader.server.{ext}

Where

  • localesDir is… (see below)
  • adapterKey is the key you used for the adapter config in wuchale.config.js, e.g. main
  • ext is one of the supported loader extensions by the adapter (see in the beginning of its page).

type: GlobConf default: (depends on adapter)

The files to extract from. Only these files will be extracted from. Other files are ignored.

type GlobConf =
| string
| string[]
| {
include: string | string[]
ignore: string | string[]
}

type: URLConf | undefined default: undefined

type URLConf = {
patterns?: string[]
localize?: boolean | string
}

The URL configuration. It should list the patterns and provide a localization method which can be:

  • true: the default localization of prefixing the path with the locale like in /en/about will be used
  • A string: a localize function from the module at the given path will be imported, whose implementation is up to the user.

The localize function should match this type:

type URLLocalizer = (url: string, locale: string) => string

See Internationalizing URLs for more.

type: StorageFactory default: pofile()

Storage handler. See the Custom storage and the Storage Interface reference for more details.

The pofile storage can be imported from wuchale and accepts an object argument of the type:

type POFileOptions = {
dir: string
separateUrls: boolean
}

to configure the directory where the catalogs are stored and whether to keep the URLs in separate catalogs.

type: CodePattern[] default: [pluralPattern]

type CodePattern = {
name: string
args: ('message' | 'pluralFunc' | 'locale' | 'other')[]
}

This specifies the function call patterns that you define to handle plurals and l10n.

The name is the name of the function.

The args array specifies the function argument sequences and each element can be one of the three:

  • message: Extractable message string. Can be:
    • A string for use with l10n libraries like IntlMessageFormat.
    • An array of strings when using it for built-in plurals.
  • pluralFunc: The function derived from the catalog plural expression (e.g. PO header) used to decide the index inside the candidate strings array.
  • other: Other arguments

The default value is a pattern to support built-in pluralization.

type: (msg: Message) => boolean | null | undefined default: (depends on adapter)

This is a function that decides whether a message is to be extracted or not. It can use the message and its details and return a boolean value to indicate its decision.

If it returns null or undefined, the default heuristic will be used. Here is the full definition of the Message type

type TxtScope = 'script' | 'markup' | 'attribute'
type HeuristicDetailsBase = {
scope: TxtScope
element?: string
attribute?: string
}
type ScriptDeclType = 'variable' | 'function' | 'class' | 'expression'
type HeuristicDetails = HeuristicDetailsBase & {
file: string
/* the type of the top level declaration */
declaring?: ScriptDeclType
/* the name of the function being defined, '' for arrow or null for global */
funcName?: string | null
/* whether the function being defined is nested inside another, null for no function */
funcIsNested?: boolean
/* whether inside a script file/<script> instead of an expression inside markup */
insideProgram: boolean
/* the name of the call at the top level */
topLevelCall?: string
/* the name of the nearest call (for arguments) */
call?: string
}
type MessageType = 'message' | 'url'
type Message = {
msgStr: string[] // array for plurals
plural: boolean
context?: string
placeholders: [number, string][]
details: HeuristicDetails
type: MessageType
}

A few interesting properties of the details are:

The file path where the message is located, relative to the root directory.

The type of the top level declaration (if in script).

Whether the message is inside a function definition. Can also be an arrow function.

The name of the call at the top level. For example,

const a = topLevel({
bar: non.topLevel('Hello'),
})

The value of topLevelCall would be topLevel

The name of the nearest call. In the above example, this would be non.topLevel.

type: boolean default: false

Whether to split the compiled catalog into smaller parts. By default it splits them into parts for each file, so that each file has its own compiled catalog.

type: (filename: string) => string default: defaultGenerateLoadID

This applies only when granularLoad is enabled. It should generate IDs for the individual parts of the compiled catalog. The IDs should be valid keywords,they can only contain alphanumeric characters and _.

If the same IDs are returned for multiple files, the resulting compiled catalog will be shared by the files. This can be used to combine and share the same compiled catalog between files with a small number of messages to reduce the number of requests.

The default generator converts the file paths into compatible IDs by replacing every special character by _.

type: boolean default: false

In some cases, avoiding async loading and directly importing the catalogs by the code that uses them may be desired. This is how Paraglide works. However, it is not recommended as all catalogs then get bundled with the code that uses them even though only one for a single locale is required by the user. This can inflate the bundle size. But if this is desired anyway, it can be enabled here.

type: string default: (undefined)

You can specify this to enable writing the transformed code. A mirror structure is created in this directory and the transformed code is put there.

This configures the specifics of the code transformation. Its type is this:

type DecideReactiveDetails<RTCtxT> = RTCtxT & { funcName?: string; nested: boolean; file: string }
type WrapFunc = (expr: string) => string
type RuntimeConfDetails = {
wrapInit: WrapFunc
wrapUse: WrapFunc
}
type RuntimeConf<RTCtxT = {}> = {
/** return null to disable */
initReactive: (details: DecideReactiveDetails<RTCtxT>) => boolean | null
useReactive: boolean | ((details: DecideReactiveDetails<RTCtxT>) => boolean)
plain: RuntimeConfDetails
reactive: RuntimeConfDetails
}

Read below for the details.

type: (see above) default: Depends on adapter

This function can decide if the runtime should be initialized in a place described by details, and if so, with which function from the loader (getLoader for plain or getLoaderRx for reactive). For example, for React, inside hooks and components, we can initialize and use the runtime from the reactive loader function. But in other functions, we have to use the non-reactive loader function. And we cannot initialize the runtime inside the top level because it cannot be updated afterwards after loadLocale. But for SolidJS, we can initialize the runtime once in the top level and use it anywhere. This function makes those decisions.

type: (see above) default: Depends on adapter

This function can decide which runtime to use between the reactive and plain. When the details have to be checked to decide, it can be given as a function. But if the answer is always the same (like always plain in JavaScript or always reactive in SolidJS), then it can be given as a boolean. If it is a boolean, it also overrides initReactive to do the same when there is a need to initialize.

type: (expr: string) => string default: Depends on adapter

For the reactive runtime initialization, we can wrap the initialization expression of the runtime to customize it to the behaviour of the library. For example, for Svelte, the default is wrapping it inside $derived and for SolidJS, making it a function, pairing it with wrapUse below.

type: (expr: string) => string default: Depends on adapter

For the reactive runtime initialization, we can wrap the referencing expression of the runtime to customize it to the behaviour of the library. For example, for Svelte, no wrapping is needed while for SolidJS, since it’s a function, it has to be called so it needs () before use.

Like runtime.reactive.wrapInit but for the non-reactive runtime.

Like runtime.reactive.wrapUse but for the non-reactive runtime.