diff --git a/chrome/content/tor-circuit-display.js b/chrome/content/tor-circuit-display.js
index e4b5ceea..fb0b8fc9 100644
--- a/chrome/content/tor-circuit-display.js
+++ b/chrome/content/tor-circuit-display.js
@@ -58,7 +58,11 @@ let createTorCircuitDisplay = (function() {
     knownCircuitIDs = new Map(),
     // A mutable map that records the SOCKS credentials for the
     // latest channels for each browser + domain.
-    browserToCredentialsMap = new Map();
+    browserToCredentialsMap = new Map(),
+    // A mutable map from stream id to .bit[.onion] domains
+    bitTargets = {},
+    // A mutable map from .bit[.onion] domains to .onion domains.
+    bitToOnionMap = {};
 
   // __trimQuotes(s)__.
   // Removes quotation marks around a quoted string.
@@ -153,6 +157,28 @@ let createTorCircuitDisplay = (function() {
     return null;
   };
 
+  // __collectBitTargets(aContoller)__.
+  // Watches for STREAM NEW events. When a NEW event occurs, we will see
+  // the stream's target domain. If that target is a .bit domain, then
+  // we want to be sure to record this so we can later record if it is
+  // remapped to a .onion domain.
+  let collectBitTargets = function (aController) {
+    return aController.watchEvent(
+      "STREAM",
+      streamEvent => streamEvent.StreamStatus === "NEW",
+      async (streamEvent) => {
+        logger.eclog(3, "new streamEvent:" + JSON.stringify(streamEvent));
+        if (streamEvent && streamEvent.StreamID && streamEvent.Target) {
+          let targetDomain = streamEvent.Target.split(":")[0];
+          if (targetDomain.endsWith(".bit") ||
+              targetDomain.endsWith(".bit.onion")) {
+            bitTargets[streamEvent.StreamID] = Services.eTLD.getBaseDomainFromHost(targetDomain);
+            logger.eclog(3, "stream on .bit domain: " + targetDomain);
+          }
+        }
+      });
+  };
+
   // __collectIsolationData(aController, updateUI)__.
   // Watches for STREAM SENTCONNECT events. When a SENTCONNECT event occurs, then
   // we assume isolation settings (SOCKS username+password) are now fixed for the
@@ -166,6 +192,15 @@ let createTorCircuitDisplay = (function() {
       "STREAM",
       streamEvent => streamEvent.StreamStatus === "SENTCONNECT",
       async streamEvent => {
+        logger.eclog(3, "sentconnect streamEvent:" + JSON.stringify(streamEvent));
+        // Collect any stream target that might be an onion.
+        if (streamEvent && streamEvent.StreamID && streamEvent.Target) {
+          let targetDomain = streamEvent.Target.split(":")[0];
+          if (targetDomain.endsWith(".onion")) {
+            bitToOnionMap[bitTargets[streamEvent.StreamID]] = targetDomain;
+            logger.eclog(3, "mapped " + bitTargets[streamEvent.StreamID] + " to " + targetDomain);
+          }
+        }
         if (!knownCircuitIDs.get(streamEvent.CircuitID)) {
           logger.eclog(3, "streamEvent.CircuitID: " + streamEvent.CircuitID);
           knownCircuitIDs.set(streamEvent.CircuitID, true);
@@ -367,7 +402,9 @@ let createTorCircuitDisplay = (function() {
       }
 
       let domainParts = [];
-      if (domain.endsWith(".onion")) {
+      logger.eclog(3, "bit to onion map:" + JSON.stringify(bitToOnionMap) + ", domain: " + domain);
+      let mappedOnion = bitToOnionMap[domain];
+      if (domain.endsWith(".onion") || mappedOnion) {
         for (let i = 0; i < 3; ++i) {
           li(uiString("relay"));
         }
@@ -380,28 +417,32 @@ let createTorCircuitDisplay = (function() {
         domainParts.push(domain);
       }
 
-      // We use a XUL html:span element so that the tooltiptext is displayed.
-      li([
-        "html:span",
-        {
-          class: "circuit-onion",
-          onclick: `
-          this.classList.add("circuit-onion-copied");
-          Cc[
-            "@mozilla.org/widget/clipboardhelper;1"
-          ].getService(Ci.nsIClipboardHelper).copyString(this.getAttribute("data-onion"))
-        `,
-          "data-onion": domain,
-          "data-text-clicktocopy": torbutton_get_property_string(
-            "torbutton.circuit_display.click_to_copy"
-          ),
-          "data-text-copied": torbutton_get_property_string(
-            "torbutton.circuit_display.copied"
-          ),
-          tooltiptext: domain,
-        },
-        ...domainParts,
-      ]);
+      if (mappedOnion) {
+        li(domain, " ", ["span", { class: "circuit-ip-address" }, mappedOnion]);
+      } else {
+        // We use a XUL html:span element so that the tooltiptext is displayed.
+        li([
+          "html:span",
+          {
+            class: "circuit-onion",
+            onclick: `
+            this.classList.add("circuit-onion-copied");
+            Cc[
+              "@mozilla.org/widget/clipboardhelper;1"
+            ].getService(Ci.nsIClipboardHelper).copyString(this.getAttribute("data-onion"))
+          `,
+            "data-onion": domain,
+            "data-text-clicktocopy": torbutton_get_property_string(
+              "torbutton.circuit_display.click_to_copy"
+            ),
+            "data-text-copied": torbutton_get_property_string(
+              "torbutton.circuit_display.copied"
+            ),
+            tooltiptext: domain,
+          },
+          ...domainParts,
+        ]);
+      }
 
       // Hide the note about guards if we are using a bridge.
       document.getElementById("circuit-guard-note-container").style.display =
@@ -534,6 +575,7 @@ let createTorCircuitDisplay = (function() {
       stopCollectingIsolationData = null,
       stopCollectingBrowserCredentials = null,
       stopEnsuringCorrectPopupDimensions = null,
+      stopCollectingBitTargets = null,
       stop = function() {
         syncDisplayWithSelectedTab(false);
         if (myController) {
@@ -546,6 +588,9 @@ let createTorCircuitDisplay = (function() {
           if (stopEnsuringCorrectPopupDimensions) {
             stopEnsuringCorrectPopupDimensions();
           }
+          if (stopCollectingBitTargets) {
+            stopCollectingBitTargets();
+          }
           myController = null;
         }
       },
@@ -554,6 +599,7 @@ let createTorCircuitDisplay = (function() {
           try {
             myController = await wait_for_controller();
             syncDisplayWithSelectedTab(true);
+            stopCollectingBitTargets = collectBitTargets(myController);
             stopCollectingIsolationData = collectIsolationData(
               myController,
               updateCircuitDisplay
