Seeking Help for Keyboard Shortcut to Switch Dictation Languages in macOS Sonoma

Hello everyone,

I'm currently using macOS Sonoma, set to Dutch, and I frequently utilize the dictation feature in both English and Dutch. However, I've encountered a bit of a cumbersome process when switching between these two languages. To switch, I need to manually click on the NL or EN icon next to the microphone icon each time.

This process feels quite tedious to me. I'm wondering if there's a more efficient way to switch dictation languages, perhaps using a keyboard shortcut? Is it possible to achieve this through a custom script?

Additionally, it would be incredibly convenient if there was a script that could automatically set the dictation to English when I press a specific key combination, and to Dutch when I press a different one.

I would greatly appreciate any advice, suggestions, or script examples that could help streamline this process.

Thank you in advance for your help!

I've never looked at the chooser for languages in Dictation before, but at first glance, it seems the only way you could automate it would be with Found Image, and it's going to be a pain. I did a brief test, and while Keyboard Maestro can find the image of the microphone and the language pop-up, I couldn't get it to stay on screen when I tried to move and click the mouse at its found image location.

And even if you get that working, you have to do it again—the first click reveals the language chooser, then you have to move and click again. So then I approached it by trying to find the setting in the OS, which I did. This setting is stored in the file named...

...which is in your user's Library > Preferences folder. However, I was unable to change it programmatically—in theory, this should set the dictation language:

defaults write "DictationIMNetworkBasedLocaleIdentifier" -string "en_US"

But it doesn't work, even after killing and restarting the prefs system when making the change. Perhaps someone else out there knows the magic to make it work, but the only way I was able to change that value was through the pop-up button.


I notice that this snippet, from Stack Overflow, seems to be working, once Dictation is activated, on Sonoma.

The tokens here are for EN ⇄ FR, so you would need to edit them.

For an execute shell script action:


k=" DictationIMLocaleIdentifier"
if [[ "$(defaults read $k)" == en-GB ]]; then
    defaults write $k fr-FR
    defaults write "Session Language" fr-FR
    defaults write $k en-GB
    defaults write "Session Language" en-GB
killall -HUP DictationIM

Nice find—killing the dictation engine was the bit I was missing. That should work really nicely for the user.


1 Like

( I think these processes typically read their plist file only load )

Yea, they do - I was trying to kill the entire prefs system to get it to re-read, but it wasn't working :).


Thank you for all the replies guys!

When I run the script, I encounter an error message on the second line, right after the second equals sign in the if condition (if [[ "$(defaults read $k)" ==).
I'm not sure if this is the reason, but the snippet from Stack Overflow dates back to 2012. Therefore, should "" be replaced with something else?

Perhaps with one of these found in the preferences folder in the user library?"

I stumbled upon a great trick on a forum that's really helpful for bilingual dictation. When I add English as an additional input source alongside Dutch, the system not only switches keyboard languages but also the dictation language seamlessly whenever I press Control-Space. I've tested it out, and it works like a charm!

1 Like

I stumbled upon a great trick on a forum that's really helpful for bilingual dictation.

Unfortunately, this also changes the keyboard layout, which is a no-go for me.

That said, I dug a little deeper into what happens when I switch dictation language using that little popup under the microphone icon when dictation is active and am happy to report that the script below works in Sonoma 14.5 (newest MacOS at this point).

Save the script e.g. as manage-dictation-language wherever you keep shell scripts e.g. $HOME/bin, make it executable via chmod 755 $HOME/bin/manage-dictation-language, then call it with the -t option form KB Maestro via a hotkey.

Note: The -t toggle option only works if you have two languages, langA and langB at the top of the script, which I have defined as en_US and de_DE for my purposes. Adjust as needed. Feel free to write a rotating logic if you have more than 2 languages or use the -s <lang> option to set a specific language.

Hope it helps!

Edit 2024-06-11: updated script to make it more robust.

summary="manage macOS dictation language"
# Modified from

# Variables
# ---------


# Options
# -------

cmd=$(basename $0)
usage="$cmd -h | {-g | -s lang | -t}"


# The following keys change in prefs when I change the language in the dictation popup:
#   DictationIMNetworkBasedLocaleIdentifier = "en_US";   <- changes to "de_DE"
#   DictationIMPreferredLanguageIdentifiers =     (      <- changes order of preference
#       "en_US",
#       "de_DE"
#   );

help=$(cat <<EOF

  $cmd -- $summary


    -h            display this help
    -g            get current language
    -s lang       set current language to <lang>
    -t            toggle the language between $langA and $langB (edit script to change)


while getopts hgs:t OPT
  case $OPT in
    h) echo "$help" >&2
       exit 0
    g) defaults read "$prefs" "$key_locale" >&2
       exit 0
    s) lang=$OPTARG
    t) toggle=1
    \?) echo $usage >&2
        exit 2

#shift $(expr $OPTIND - 1)

test $# -eq 0 && echo -e "Nothing to do. Usage:\n\n    $usage\n" && exit 0

# Run

if [ "$lang" = "" ]                     # treat not setting a language as toggle
then                                    # toggle
  cur="$(defaults read "$prefs" "$key_locale")"
  case "$cur" in
    "$langA") lang1="$langB"; lang2="$langA" ;;
    "$langB") lang1="$langA"; lang2="$langB" ;;
    *) echo "current language '$cur' is not one of '$langA' or '$langB'" >&2
       exit 2
else                                    # set language
  case "$lang" in
    "$langA") lang1="$langA"; lang2="$langB" ;;
    "$langB") lang1="$langB"; lang2="$langA" ;;
    *) echo "language '$lang' is not one of '$langA' or '$langB'" >&2
       exit 2

defaults write "$prefs" "$key_locale" "$lang1"
defaults write "$prefs" "$key_order" "($lang1, $lang2)"

# Not used
#defaults write "Session Language" "$lang"

# DictationIM is the Input Method-based process that implements the UI
# portion of the Dictation feature in macOS. If it doesn't exist, it will
# launch automatically, so don't error here
killall -HUP DictationIM 2>/dev/null || true

1 Like