diff --git a/src/assets/stylesheets/ui-root.scss b/src/assets/stylesheets/ui-root.scss
index f632f83832dbfdd0156d0f096adf04b5abe384e1..cdd7daa64863907be58fd7ab404a6dc40c0254b7 100644
--- a/src/assets/stylesheets/ui-root.scss
+++ b/src/assets/stylesheets/ui-root.scss
@@ -262,7 +262,7 @@
   }
 }
 
-:local(.message-entry-in-room):hover {
+:local(.message-entry-in-room):focus-within {
   opacity: 1.0;
   transition: opacity 0.25s linear;
 
diff --git a/src/hub.html b/src/hub.html
index 99232684d4d2da80d13a3e953ffad076f3eeb748..fc27508c6827eca9eb4e72b2638cd75e8ec5bb61 100644
--- a/src/hub.html
+++ b/src/hub.html
@@ -32,6 +32,7 @@
         vr-mode-ui="enabled: false"
         stats-plus="false"
         action-to-event__mute="path: /actions/muteMic; event: action_mute;"
+        action-to-event__focus_chat="path: /actions/focusChat; event: action_focus_chat;"
     >
 
         <a-assets>
diff --git a/src/hub.js b/src/hub.js
index 01e04f4acb4cd6fc9d602b313d213d9b6bfdddc0..ebf36bed81f532cf114c5570ca043185da43d72d 100644
--- a/src/hub.js
+++ b/src/hub.js
@@ -297,6 +297,7 @@ document.addEventListener("DOMContentLoaded", async () => {
 
   registerNetworkSchemas();
   remountUI({ hubChannel, linkChannel, enterScene: entryManager.enterScene, exitScene: entryManager.exitScene });
+  scene.addEventListener("action_focus_chat", () => document.querySelector(".chat-focus-target").focus());
 
   pollForSupportAvailability(isSupportAvailable => remountUI({ isSupportAvailable }));
 
diff --git a/src/react-components/ui-root.js b/src/react-components/ui-root.js
index c7cd0738a1967fe85f46ab88dd1079096e720554..c779d33fd89b4fe400e3520b0d93c488b0e47a63 100644
--- a/src/react-components/ui-root.js
+++ b/src/react-components/ui-root.js
@@ -690,7 +690,7 @@ class UIRoot extends Component {
           <form onSubmit={this.sendMessage}>
             <div className={styles.messageEntry} style={{ height: pendingMessageFieldHeight }}>
               <textarea
-                className={styles.messageEntryInput}
+                className={classNames([styles.messageEntryInput, "chat-focus-target"])}
                 value={this.state.pendingMessage}
                 rows={textRows}
                 style={{ height: pendingMessageTextareaHeight }}
@@ -699,6 +699,8 @@ class UIRoot extends Component {
                 onKeyDown={e => {
                   if (e.keyCode === 13 && !e.shiftKey) {
                     this.sendMessage(e);
+                  } else if (e.keyCode === 27) {
+                    e.target.blur();
                   }
                 }}
                 placeholder="Send a message..."
@@ -1006,7 +1008,11 @@ class UIRoot extends Component {
               <div className={styles.messageEntryInRoom} style={{ height: pendingMessageFieldHeight }}>
                 <textarea
                   style={{ height: pendingMessageTextareaHeight }}
-                  className={classNames([styles.messageEntryInput, styles.messageEntryInputInRoom])}
+                  className={classNames([
+                    styles.messageEntryInput,
+                    styles.messageEntryInputInRoom,
+                    "chat-focus-target"
+                  ])}
                   value={this.state.pendingMessage}
                   rows={textRows}
                   onFocus={e => e.target.select()}
@@ -1017,6 +1023,8 @@ class UIRoot extends Component {
                   onKeyDown={e => {
                     if (e.keyCode === 13 && !e.shiftKey) {
                       this.sendMessage(e);
+                    } else if (e.keyCode === 27) {
+                      e.target.blur();
                     }
                   }}
                   placeholder="Send a message..."
diff --git a/src/systems/userinput/bindings/keyboard-mouse-user.js b/src/systems/userinput/bindings/keyboard-mouse-user.js
index 1f067d4447effc86541b93d26fb32ffaba5e471b..1c41ea12841d6487fda9f582c90714282a7d0ffc 100644
--- a/src/systems/userinput/bindings/keyboard-mouse-user.js
+++ b/src/systems/userinput/bindings/keyboard-mouse-user.js
@@ -108,6 +108,15 @@ export const keyboardMouseUserBindings = {
       },
       xform: xforms.rising
     },
+    {
+      src: {
+        value: paths.device.keyboard.key("t")
+      },
+      dest: {
+        value: paths.actions.focusChat
+      },
+      xform: xforms.rising
+    },
     {
       src: {
         value: paths.device.keyboard.key("l")
diff --git a/src/systems/userinput/paths.js b/src/systems/userinput/paths.js
index d9f74a9ac6e437ead10d2e57237275c2de44aa44..4d5b0fd9dbb242be53f9d8fb938353add5e353de 100644
--- a/src/systems/userinput/paths.js
+++ b/src/systems/userinput/paths.js
@@ -13,6 +13,7 @@ paths.actions.startGazeTeleport = "/actions/startTeleport";
 paths.actions.stopGazeTeleport = "/actions/stopTeleport";
 paths.actions.spawnPen = "/actions/spawnPen";
 paths.actions.muteMic = "/actions/muteMic";
+paths.actions.focusChat = "/actions/focusChat";
 paths.actions.cursor = {};
 paths.actions.cursor.pose = "/actions/cursorPose";
 paths.actions.cursor.grab = "/actions/cursorGrab";