# RemoteLocaleSource > Locales fetched over HTTP from a manifest you host, with an on-disk cache served when the host is unreachable. `gg.lode.bookshelflocales.source.RemoteLocaleSource` --- ## Signature ```java public final class RemoteLocaleSource implements LocaleSource ``` Hard-code one manifest URL and your plugin can ship no locale files at all — new languages and typo fixes reach servers on the next reload, with no plugin update. --- ## Manifest Format A flat JSON object of language code to download URL: ```json { "en_us": "https://cdn.example.com/locales/en_us.json", "ja_jp": "https://cdn.example.com/locales/ja_jp.json" } ``` Relative entries such as `"en_us.json"` resolve against the manifest's own URL. Each linked document is an ordinary locale file. --- ## Methods | Method | Return Type | Description | |--------|-------------|-------------| | `header(String name, String value)` | `RemoteLocaleSource` | Adds a request header sent with the manifest and every locale download. | | `timeout(Duration timeout)` | `RemoteLocaleSource` | Per-request timeout. Defaults to 10 seconds. | | `cacheFolder(Path folder)` | `RemoteLocaleSource` | Writes each successful download to disk and serves that copy when the host is unreachable. | | `manifestUrl()` | `String` | The configured manifest URL. | | `isRemote()` | `boolean` | Always `true`, grouping this source with `reloadFromCloud()`. | All setters return the source, so they chain. --- ## Failure Behavior | Failure | Result | |---|---| | Manifest unreachable, cache configured | The cached locales are served and a warning is logged. | | Manifest unreachable, no cache | Nothing is returned; [[LocaleManager]] keeps the previous copy rather than dropping to raw keys. | | One locale fails to download | That locale falls back to its cached copy; the others load normally. | | Malformed manifest | Warning naming the URL; the source returns its cache, if any. | A CDN outage costs you fresh text, not all text. --- ## Usage ```java LocaleManager locales = LocaleManager.builder() .defaultLocale("en_us") .remote("https://cdn.example.com/locales/manifest.json", source -> source .header("Authorization", "Bearer " + token) .timeout(Duration.ofSeconds(5)) .cacheFolder(getDataFolder().toPath().resolve("locales-cache"))) .folder(getDataFolder().toPath().resolve("locales")) .build(); locales.reloadFromCloudAsync(); ``` > [!warning] Never fetch on the main thread > Loading this source blocks on HTTP. Use `reloadFromCloudAsync()` from command handlers. Register remote sources **before** `folder(...)`: hosted locales are still defaults, so a server owner's local edit should outrank them. --- ## Related Pages - [[LocaleSource]] - [[LocaleManager]] - [[Bookshelf/Developers/Locales]]