Translate
Type in one language, read the translation live, and drop it into the field without switching apps. Online, or on the device with no connection.
Translate opens a small typing window right above the keys. It grows with your phone’s font size, so the translation under the language chips stays readable at a large text size. Type a sentence, or paste one, watch the translation appear as you go, then send it to your field with a tap. It translates whatever is in the panel’s own text box, so it works the same in a chat app, a note, or a search bar. The one thing it reads from your field is text you selected before you opened it.
Using it
Section titled “Using it”Open Translate from the toolbar, or from the toolbox if you haven’t pinned it (it isn’t pinned by default). On a hardware keyboard, use the leader key: double-tap Ctrl, then press R.
The panel has its own text box at the top, which wraps onto several lines and scrolls once it holds more than four or so. Enter starts a new line in it rather than closing it. What you type there is what gets translated, not the text already in your field. It’s the same key-rerouting trick the GIF, sticker, and Wikipedia panels use: while the panel is focused, your keystrokes go to its text box instead of the app behind the keyboard. Opening Translate over a chat you’re mid-way through never touches what you already wrote.
Translating text you selected. Select some text in the field first, then open Translate, and the selection is already in the box with its translation under it. That is the way to translate a message in a language you can’t type. The panel reads the selection once, as it opens, and never from a password field. With nothing selected, the box starts empty. The selection actions bar has a Translate chip that does the same in one tap.
Pasting into the box. The clipboard icon in the box’s top corner pastes the text you copied last, without opening the clipboard. An image on the clipboard is skipped. If you weren’t typing in the box, the translation runs straight away and stays on screen with the keys out of the way; if you were, the text goes in at the cursor and you carry on typing. You can also long-press the box where there is no word (an empty box anywhere) and a Paste bar comes up at the caret, with Select all beside it once the box holds text. Long-press a word to select it instead, and the bar offers Cut, Copy, Paste and Select all. The toolbar’s Paste tool, and a layout’s Paste key, paste into the box too while it has the keys. This works in every one of the keyboard’s own text boxes, not only this one; see A captured box is a real text field.
The header reads left to right like a sentence: from this language, to that one, using this engine.
- Source language is the first chip. It starts on Detect language and switches to the language it found once a result comes back, for example “Bengali”. Tap it to pick the source yourself when the detection is wrong, which mostly happens with a word or two. Your pick lasts until you close the panel. Pick Detect language to hand it back.
- Swap is the arrows between the chips. It turns the translation round: the result becomes the text, its language the source, and the language it was read as the new target. It lights up once there is a result to swap.
- Target language is the second chip. Tap it to open a dropdown of all 63 languages and pick one.
- Engine is the chip on the right, Full edition only only: Online, On device or Automatic. See On-device translation below.
- The translation updates automatically about 400 milliseconds after you stop typing. Pressing return translates immediately, and changing the target language re-translates what’s already in the box right away.
- Once a translation is showing, two actions light up below it:
- Insert types the translation into your field at the cursor, leaving whatever was already there in place.
- Replace text swaps out the field’s entire contents for the translation. Use this when the field only holds the sentence you were translating and you want a clean swap rather than an insertion. When the panel opened on a selection, it replaces only that selection, as long as the text is still selected. If you have since moved off it, the translation goes in at the cursor instead, so the text around the passage is never lost.
While you type, the panel shrinks to leave room for the keys, and a long text gives way first: the box shows three lines, then scrolls, so the language chips, Replace text and Insert always stay on screen below it. While your text is shorter than that, the translation gets the spare room. With the keys away, the box shows up to five lines.
On a phone turned sideways the panel is short, so it rearranges rather than stacking: the language chips, Replace text and Insert move up into the panel’s header, and the text you type sits on the left with its translation beside it on the right. While you type, with the keys back under the panel, there is only room for one row, so that row holds your text, its translation, Replace text and Insert, and the language chips move below it when the screen has space for them.
Long input is capped: anything past 2,500 characters is silently cut off before it’s sent, with no on-screen warning that it happened.
On-device translation
Section titled “On-device translation”Full edition only The Full edition can translate on the phone with Google’s ML Kit, with no connection and without the text leaving the device. Pick the engine from the chip on the panel or under Options:
- Online (the default) is what Translate has always done: Google’s endpoint, your Cloud key, or your LibreTranslate server, unless you set up DeepL or your own translation server. It knows the most languages and gives the best translations.
- On device never sends the text anywhere. It needs a model for each language, about 30 MB each, downloaded once.
- Automatic uses the device whenever the languages are downloaded, and the online service for everything else: a language with no model, a pair you have not downloaded, text the device cannot read. The engine chip’s icon shows which one produced the result on screen.
On Google Play, the engine is a download too. The Play edition keeps ML Kit’s translator out of the install, because it is about 16 MB that most people never use. On device is the Play edition’s default engine, so the first translation offers the download, and picking On device or Automatic later asks Google Play for it straight away. The panel and the Tools / Translate page show that download and carry on by themselves when it lands, with no restart. If Play cannot deliver it, the panel says so and the button tries again. APKs from GitHub carry the engine inside and skip this step.
Models. Each language is one download, and every model translates to and from English. Bengali to German therefore needs both the Bengali and the German model and goes through English on the way, which costs some accuracy. English itself is part of the engine and is never downloaded. When a translation needs a model you do not have, the result area says which and how big, and the action row becomes a Download button. The same button cancels while the download runs. When the models arrive, the text you typed is translated at once. Downloads also show in the notification shade, and they carry on if you close the panel. With data saver holding downloads on a metered connection, the button asks first and a second press is the yes.
Which languages. 59 of the 63: everything in the list except Malayalam, Nepali, Punjabi and Traditional Chinese (the Chinese model is Simplified). With the engine on On device or Automatic, the language menus mark downloaded languages with a tick and the ones the device cannot do with Online only, and list the downloaded ones first.
A short list on the device. With the engine on On device, each language menu lists only what it can use now: the downloaded languages (and any on their way), the languages you type in, and the current selection. All languages, the last row, opens the rest of that menu, so you can still pick a language and download it from the offer. The next menu opens short again. Automatic always lists every language, because it sends the ones you have not downloaded online. Both behaviours are switches under Options.
Detecting the source. ML Kit’s translator has to be told what it is reading, so a separate on-device language identifier (bundled, no download) does the detecting. It is reliable on a sentence and shaky on a word or two. When it is not sure, the keyboard falls back on the languages you type in, the active one first, and shows the source with a question mark, as in “French?”. Tap the chip to correct it. Hindi, Japanese, Russian, Arabic, Greek, Bulgarian or Chinese typed in Latin letters is recognised for what it is and refused on the device, because no model reads it; Automatic sends it online instead.
What to expect. On-device translation is good for messages and short text and noticeably less exact than the online service on long, technical or idiomatic text. Line breaks and blank lines survive: each line is translated on its own. The translators are unloaded when you close the panel, since a loaded language pair holds tens of megabytes of memory.
Your own translation server
Section titled “Your own translation server”You can send translations to a server that you run, or to a service that you pay for, as long as it answers OpenAI chat completion requests (/v1/chat/completions). llama.cpp’s llama-server, Ollama, LM Studio, vLLM and LocalAI all do, and so do most hosted gateways. The keyboard itself then does no translating work: the phone only sends the text and shows the answer.
- Turning it on. Type the server’s address under Options. Nothing changes until you do. The Online engine then sends every translation to your server. On Automatic, only the translations that the device cannot do go to it. On device never uses it.
- Nothing else gets the text. With an address set, the server replaces DeepL, Google and LibreTranslate for all languages. When the server fails (it is off, the address is wrong, the model is missing), the panel shows the error and the text goes nowhere else. A small Your server label beside the engine chip says where the translation on screen came from.
- What the server gets. A chat with two messages: an instruction to translate into the target language (and from the source language, if you picked one in the panel), then your text as the second message. The instruction tells the model to reply with the translation only and to translate questions and requests rather than answer them. The answer comes back as it is written, and the keyboard removes a
<think>block and a pair of quotation marks around the whole answer, if the model adds them. - The address. A bare
host:port, the API root (http://192.168.1.10:8080/v1,https://openrouter.ai/api/v1) or the whole…/chat/completionsaddress all work. With no path, the keyboard adds/v1. With nohttp://orhttps://, it useshttps://, so typehttp://for a server on your home network. - Which language it read. The server does not say what language the text was in, so the source chip shows a language only when you picked one.
- Speed. A language model is slower than a translation service. On a small model, expect a second or more for a sentence; a model that reasons first takes longer.
DeepL is an optional online service that you bring yourself, with your own DeepL API key. Nothing about it shows or runs until you add a key (or a server address) under Options. The keyboard has no DeepL key of its own.
- Translate with DeepL. With a key set, the online engine asks DeepL instead of Google or LibreTranslate. A small DeepL label beside the engine chip says when DeepL made the translation on screen. For a language pair that DeepL does not have, the keyboard uses the usual service for that pair and the label goes away. On Automatic, DeepL only takes the part that would otherwise go online.
- DeepL Write. Off until you turn it on. Write corrects and rewrites text in its own language: grammar, wording, style and tone. It adds a button to the Grammar check panel and a DeepL Write action to selection actions. DeepL sells Write with API Pro plans only, so a Free key gets an error from it (Free keys still translate).
- Which server. DeepL API Free keys end in
:fxand go toapi-free.deepl.com; every other key goes toapi.deepl.com. The keyboard picks the server from the key. DeepL server replaces both, for a proxy that you run and that answers DeepL’s/v2/translaterequests. - Limits. The Free plan includes 500,000 characters each month. When the month’s characters are used up, the panel says so.
Options
Section titled “Options”- Turn on: already on, like every tool. Switching it off removes Translate from both the toolbar and the toolbox.
- Icon colour: only shown if colorful tool icons are turned on globally. It overrides Translate’s icon color.
- Keyword shortcut: a Trigger words field pre-filled with “translate”, plus a Match capitals switch that’s off by default. Type the word on its own and the suggestion strip offers to open the tool. See smart suggestion chips.
- Translate into: the target language, from the same 63-language list as the panel’s picker. Defaults to English. Changing it here also changes what the panel opens to next time.
- Translation engine: Full edition only Online, On device or Automatic. The same choice as the panel’s engine chip. The default is On device on Google Play and Online in the APKs from GitHub.
- Downloaded languages first: Full edition only on by default. On On device and Automatic, the panel’s language menus start with the languages on the device. Off keeps the usual order: English and Bengali, then the rest by name.
- Only downloaded languages: Full edition only on by default. On On device, the panel’s language menus show the downloaded languages, the languages you type in and the current selection, with All languages at the end for the rest. Off lists every language.
- Languages on the device: Full edition only the on-device models. The list starts with English (built in), the language you translate into, the languages you type in, and anything already downloaded or on its way. More languages below it folds out the rest. Each row downloads, cancels or deletes one model and shows its progress. A download started here shows as running in the panel, and the other way round.
- LibreTranslate server: F-Droid build only, blank by default. Paste the address of a LibreTranslate server, your own or one you trust. Translation goes there instead of Google, even if a Cloud Translation key is also set. An optional key field sits below it, for instances that ask for one. See Servers for the same field shared across tools.
- Server address: blank by default, and the switch that turns your own translation server on.
- Model (optional): blank by default, which sends no model name, for a server that has one model. Type the model’s name as the server knows it (for example
qwen3:4bon Ollama) when it has several. - Server API key (optional): blank by default. Sent as a bearer token, for a server or a service that asks for a key.
- DeepL API key: blank by default, and the switch that turns DeepL on. See DeepL. The key rows below it show only once a key or a server is set.
- DeepL server (optional): blank by default, which means DeepL’s own server for your kind of key. Paste an address to send DeepL requests to a proxy instead.
- Translate with DeepL: on by default. Off keeps the key for DeepL Write only, and translation goes to the usual service.
- DeepL Write: off by default. On adds DeepL Write to the Grammar check panel and to selection actions. Needs a DeepL API Pro key.
- Writing style: shown while DeepL Write is on. As it is (default), Simple, Business, Academic, Casual, Friendly, Confident, Diplomatic or Enthusiastic. A language that DeepL has no styles for gets a plain rewrite.
- Cloud Translation API key (optional): blank by default. Paste a Google Cloud Translation API key here to use the official API instead of the free endpoint (see below). The field saves as you type, with no separate save button. Under it you’ll read “The app uses your key” once you’ve typed one, “This field is blank. The app uses the key that is built into the app.” if this build ships one, or “Without a key, translation uses the free public endpoint of Google” otherwise.
This screen also shows the caption WM Keyboard displays right on the settings page:
The keyboard sends the text that you translate to Google either way, and only while the translate panel is open. The free endpoint is unofficial and rate limited. A Cloud Translation key makes it official and reliable. If you set up DeepL below, DeepL gets the text instead, and Google gets only the languages that DeepL does not have.
If you back up your settings with Include API keys turned on, a Translate key, DeepL key or translation server key you’ve pasted in travels with the backup along with your GIF, search, and AI keys. Without that switch, none of them leaves the phone in a backup.
Details & edge cases
Section titled “Details & edge cases”- On the device, nothing is sent. With the engine on On device, the text you type is translated by ML Kit on the phone and goes nowhere. The only network use is the model downloads, which come from Google’s servers (
dl.google.com) through Android’s download manager, plus ML Kit’s own diagnostics. On Automatic, text goes online only when the device cannot translate it. - Google, or LibreTranslate on the F-Droid build. On the online engine, with no key, WM Keyboard calls Google’s free public translation endpoint. It’s the same unofficial one browser translate extensions use: fine for personal typing volumes, with no uptime guarantee and its own rate limits. With a key, it calls the official Cloud Translation v2 API instead, billed to your Google Cloud project and reliable. The F-Droid build adds a third path: paste a LibreTranslate server’s address under Options. Every translation then goes there instead of either Google option, even with a Cloud Translation key also set. Whichever is active, only the text in the panel’s box is sent: what you typed, pasted, or had selected when you opened it. Nothing else in the field is.
- Your own server, when you set it up. With a server address, every online translation goes to that server and to nothing else, errors included (see Your own translation server). It receives the text as the user message of a chat request, in a POST body, with the instruction as the system message and your key, if any, in a request header.
- DeepL, when you set it up. With a DeepL key, translations go to DeepL first (see DeepL). A pair that DeepL turns down goes to Google or LibreTranslate as above, and DeepL is not asked about that pair again until the keyboard restarts. Any other DeepL error (a wrong key, a used-up month) shows in the panel and is not sent anywhere else.
- Sent, precisely: the text currently in the panel’s search box (truncated to 2,500 characters), the target language code, the source language code if you picked one, and your key where one applies. DeepL receives the text in a POST body and the key in a request header. The free Google endpoint receives the text as part of the request URL. The official Google API and a configured LibreTranslate server both send it in a POST body, LibreTranslate’s carrying its optional key alongside.
- When it’s sent: automatically ~400ms after you stop typing, immediately on return or retry, and immediately again if you change the target language, all only while the panel is open. Closing the panel cancels any translation in flight.
- Power Saving mode’s “Background network” toggle doesn’t touch this. That toggle only stops fetches that happen without you asking: link previews, QR auto-scan, dictionary look-ups. Tools you open yourself, translate included, keep working even with it on.
- Not available before your phone is unlocked once after a restart. Translate isn’t on the short list of tools that work on a locked device, and the on-device models live in storage that is locked until then. It won’t appear if you’re typing on the lock screen before that first unlock.
- Online translation works the same in both editions. The on-device engine is Full only, because ML Kit is. Lite and the F-Droid build have no engine chip and no model list, and translate online exactly as before.
- Deleting a model frees its space at once. If the panel was using it, the next translation asks for it again.
- If a request fails outright, from no connection, a bad key, or a timeout, the panel shows the raw error message rather than a simplified one. An offline failure can read as a technical exception string instead of “No internet connection.”
- Online, with no connection. Turn on Use on-device models offline and the Online engine hands the text to the on-device engine when the phone is offline or the service does not answer, as long as both languages are downloaded. The result says On device, offline. This goes for your own translation server too: the text still stays on the phone.
Looking for something different named “translate”? The AI tool has its own Translate action, which uses an LLM for more natural phrasing than a literal translation. When you give it a chip of its own on the selection actions bar, that chip reads AI translate, to tell it apart from the Translate chip that opens this tool. Offline voice dictation has a separate “Translate to English” toggle for what you say rather than what you type. Both are configured on their own settings screens, independent of this one. For the full picture of what leaves your device and when, see network policy.
