# LocaleManager
> The entry point of Bookshelf-Locales. Built once per plugin, holds the loaded translations, and reads from layered sources.
`gg.lode.bookshelflocales.LocaleManager`
---
## Signature
```java
public final class LocaleManager implements LocaleService
```
Construct with `LocaleManager.builder()`. Sources are loaded during `build()`.
---
## Builder
| Method | Description |
|--------|-------------|
| `defaultLocale(String languageCode)` | Locale used when none is given, and the fallback for untranslated keys. Defaults to `en_us`. |
| `bundled(ClassLoader loader, String basePath, String... languageCodes)` | Locales shipped inside your jar, e.g. `locales/en_us.json`. |
| `bundled(ClassLoader loader, String basePath, Collection<String> languageCodes)` | As above, taking a collection. |
| `remote(String manifestUrl)` | Locales fetched from a manifest you host. |
| `remote(String manifestUrl, Consumer<RemoteLocaleSource> configurer)` | As above, exposing the source for headers, timeout, and cache folder. |
| `folder(Path folder)` | The server owner's folder of `*.json` locales, and the export target below. |
| `exportBundledDefaults(boolean)` | Writes bundled locales into the folder when absent. Never overwrites an existing file. |
| `logger(Consumer<String> logger)` | Where load warnings go. Silent by default. |
| `source(LocaleSource source)` | Adds any source directly, including a custom implementation. |
| `build()` | Loads every source and returns the manager. |
Sources are read in the order they were added, and **a later source wins per key**.
---
## Methods
Everything on [[LocaleService]], plus:
| Method | Return Type | Description |
|--------|-------------|-------------|
| `localeOrDefault(String languageCode)` | `String` | The code if that locale loaded, otherwise the default. Lets you pass a player's client locale straight through. |
| `reload(Predicate<LocaleSource> filter)` | `void` | Re-reads only the sources the filter accepts. |
| `reloadAsync()` | `CompletableFuture<Void>` | `reload()` off the calling thread. |
| `reloadFromDiskAsync()` | `CompletableFuture<Void>` | `reloadFromDisk()` off the calling thread. |
| `reloadFromCloudAsync()` | `CompletableFuture<Void>` | `reloadFromCloud()` off the calling thread. |
> [!warning] Never fetch on the main thread
> `reload()` and `reloadFromCloud()` block on HTTP when a remote source is configured.
---
## Constants
| Constant | Value | Description |
|---|---|---|
| `DISPLAY_NAME_KEY` | `locale.display_name` | Key a locale uses to name itself in a language picker. |
| `SORT_ORDER_KEY` | `locale.sort_order` | Key controlling position in `getLocales()`. Lower comes first. |
---
## Reload Behavior
A partial reload re-reads only the matching sources and re-merges them over what the others last returned, always in the configured order — so precedence cannot shift.
If a source suddenly returns nothing, such as an unreachable host with no cache or an emptied folder, its previous copy is kept and a warning is logged rather than the plugin dropping to raw keys.
---
## Usage
```java
LocaleManager locales = LocaleManager.builder()
.defaultLocale("en_us")
.bundled(getClass().getClassLoader(), "locales", "en_us", "ja_jp")
.remote("https://cdn.example.com/locales/manifest.json")
.folder(getDataFolder().toPath().resolve("locales"))
.exportBundledDefaults(true)
.logger(getLogger()::warning)
.build();
locales.reloadFromDisk(); // admin edited a file
locales.reloadFromCloudAsync(); // new hosted translations published
```
---
## Related Pages
- [[LocaleService]]
- [[LocaleSource]]
- [[RemoteLocaleSource]]
- [[Bookshelf/Developers/Locales]]