diff --git a/scripts/default.env b/scripts/default.env
index b5dbe2c7c9ec3b22eba8d36f07c2fbd700bf0cb0..f26d4c84db07c28644e7c9d479842e6c771b1596 100644
--- a/scripts/default.env
+++ b/scripts/default.env
@@ -1,6 +1,6 @@
 # This origin trial token is used to enable WebVR and Gamepad Extensions on Chrome 62+
 # You can find more information about getting your own origin trial token here: https://github.com/GoogleChrome/OriginTrials/blob/gh-pages/developer-guide.md
-ORIGIN_TRIAL_TOKEN="ArEZ0vY0uMo3pj+oY8Up4u4Hy8QolJwKxG4/2WRhSPnTZRrviiGhzP6/y72nBdsIhdEyoundxqg//KLbs2vGnQoAAABkeyJvcmlnaW4iOiJodHRwczovL3JldGljdWx1bS5pbzo0NDMiLCJmZWF0dXJlIjoiV2ViVlIxLjFNNjIiLCJleHBpcnkiOjE1MjYzNDg2MjEsImlzU3ViZG9tYWluIjp0cnVlfQ=="
+ORIGIN_TRIAL_TOKEN="AgN/JtqSF6qpD3OZk8KgM5/UYqUUrwc166cOQSRCqvU+TIpHWdiwBUWH5V1K/jJkdtBrO4Q5I0XSGm16uB/Y4QQAAABVeyJvcmlnaW4iOiJodHRwczovL2h1YnMubW96aWxsYS5jb206NDQzIiwiZmVhdHVyZSI6IldlYlZSMS4xTTYyIiwiZXhwaXJ5IjoxNTI4MjQ1ODI1fQ=="
 ORIGIN_TRIAL_EXPIRES="2018-05-15"
 JANUS_SERVER="wss://prod-janus.reticulum.io"
 DEV_RETICULUM_SERVER="dev.reticulum.io"
diff --git a/src/assets/images/hub-preview.png b/src/assets/images/hub-preview.png
new file mode 100755
index 0000000000000000000000000000000000000000..5a976607e2539031d67dc17e727ecff02740c3ad
Binary files /dev/null and b/src/assets/images/hub-preview.png differ
diff --git a/src/assets/stylesheets/footer.scss b/src/assets/stylesheets/footer.scss
index f0a48bc6d15b8c1efab6c902f7e7024985f12f5f..5f782fd03c56c8be7f7115b1a99519c22ad26804 100644
--- a/src/assets/stylesheets/footer.scss
+++ b/src/assets/stylesheets/footer.scss
@@ -10,7 +10,7 @@
   // Position above virtual gamepad controls on mobile
   z-index: 1;
 
-  @media (min-width: 769px) and (min-height: 401px) {
+  @media (min-width: 769px) and (min-height: 421px) {
     pointer-events: auto;
   }
 }
@@ -35,25 +35,25 @@
   background-color: transparent;
   border-bottom: 1px solid rgba(32, 32, 32, 0.65);
 
-  @media (min-width: 769px) , (max-height: 401px) {
+  @media (min-width: 769px) , (max-height: 421px) {
     display: none;
   }
 }
 :local(.header) {
   background-color: rgba(0, 0, 0, 0.65);
 
-  @media (max-width: 768px) , (max-height: 400px) {
+  @media (max-width: 768px) , (max-height: 420px) {
     background-color: transparent;
   }
 
   :local(.hub-info) {
-    @media (max-width: 768px) , (max-height: 400px) {
+    @media (max-width: 768px) , (max-height: 420px) {
       display: none;
     }
   }
 
   :local(.hub-stats) {
-    @media (max-width: 768px) , (max-height: 400px) {
+    @media (max-width: 768px) , (max-height: 420px) {
       display: none;
     }
   }
@@ -64,7 +64,7 @@
   margin: 16px 24px;
   display: flex;
   align-items: center;
-  @media (max-width: 768px) , (max-height: 400px) {
+  @media (max-width: 768px) , (max-height: 420px) {
     margin: 16px 8px;
     margin-left: 24px;
     font-size: 0.9em;
@@ -76,10 +76,10 @@
   display: flex;
   align-items: center;
   justify-content: flex-end;
-  @media (min-width: 769px) and (min-height: 401px) {
+  @media (min-width: 769px) and (min-height: 421px) {
     flex: 1;
   }
-  @media (max-width: 768px) , (max-height: 400px) {
+  @media (max-width: 768px) , (max-height: 420px) {
     margin: 16px 8px;
   }
   :local(.hub-participant-count) {
@@ -109,13 +109,13 @@
   }
 
   :local(.menu-button__narrow-close-icon) {
-    @media (max-width: 768px) , (max-height: 400px) {
+    @media (max-width: 768px) , (max-height: 420px) {
       display: none;
     }
   }
 
   :local(.menu-button__wide-close-icon) {
-    @media (min-width: 769px) and (min-height: 401px) {
+    @media (min-width: 769px) and (min-height: 421px) {
       display: none;
     }
   }
diff --git a/src/hub.html b/src/hub.html
index 581bc3ffe008dc53cb4be3c414c119935af629e6..1f90a6be22672706204b467aa5fb54769293d9ad 100644
--- a/src/hub.html
+++ b/src/hub.html
@@ -2,6 +2,8 @@
 <html>
 
 <head>
+    <!-- DO NOT REMOVE/EDIT THIS COMMENT - HUB_META_TAGS -->
+
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="<%= ORIGIN_TRIAL_EXPIRES %>" content="<%= ORIGIN_TRIAL_TOKEN %>">
diff --git a/src/hub.js b/src/hub.js
index 26b9e1f368908a0b94a4612193cd722d1b11f38b..3d3098cf282ddd4d7677d925523ed9b391e8eabb 100644
--- a/src/hub.js
+++ b/src/hub.js
@@ -308,8 +308,24 @@ const onReady = async () => {
     }
   };
 
+  const getPlatformUnsupportedReason = () => {
+    if (typeof RTCDataChannelEvent === "undefined") {
+      return "no_data_channels";
+    }
+
+    return null;
+  };
+
   remountUI({ enterScene, exitScene });
 
+  const platformUnsupportedReason = getPlatformUnsupportedReason();
+
+  if (platformUnsupportedReason) {
+    remountUI({ platformUnsupportedReason: platformUnsupportedReason });
+    exitScene();
+    return;
+  }
+
   getAvailableVREntryTypes().then(availableVREntryTypes => {
     remountUI({ availableVREntryTypes });
   });
diff --git a/src/react-components/ui-root.js b/src/react-components/ui-root.js
index 43d39ba0a1e442f55dc095b29e63b64096be68ae..ab1d0229b0b529a6e3d9131df82e683f6097e11a 100644
--- a/src/react-components/ui-root.js
+++ b/src/react-components/ui-root.js
@@ -69,6 +69,7 @@ class UIRoot extends Component {
     initialEnvironmentLoaded: PropTypes.bool,
     janusRoomId: PropTypes.number,
     roomUnavailableReason: PropTypes.string,
+    platformUnsupportedReason: PropTypes.string,
     hubName: PropTypes.string,
     occupantCount: PropTypes.number
   };
@@ -512,18 +513,9 @@ class UIRoot extends Component {
   };
 
   render() {
-    if (this.state.exited || this.props.roomUnavailableReason) {
+    if (this.state.exited || this.props.roomUnavailableReason || this.props.platformUnsupportedReason) {
       let subtitle = null;
-      if (this.props.roomUnavailableReason !== "closed") {
-        const exitSubtitleId = `exit.subtitle.${this.state.exited ? "exited" : this.props.roomUnavailableReason}`;
-        subtitle = (
-          <div>
-            <FormattedMessage id={exitSubtitleId} />
-            <p />
-            You can also <a href="/">create a new room</a>.
-          </div>
-        );
-      } else {
+      if (this.props.roomUnavailableReason === "closed") {
         // TODO i18n, due to links and markup
         subtitle = (
           <div>
@@ -537,7 +529,34 @@ class UIRoot extends Component {
             If you have questions, contact us at <a href="mailto:hubs@mozilla.com">hubs@mozilla.com</a>.
             <p />
             If you&apos;d like to run your own server, hubs&apos;s source code is available on{" "}
-            <a href="https://github.com/mozilla/hubs">Github</a>.
+            <a href="https://github.com/mozilla/hubs">GitHub</a>.
+          </div>
+        );
+      } else if (this.props.platformUnsupportedReason === "no_data_channels") {
+        // TODO i18n, due to links and markup
+        subtitle = (
+          <div>
+            Your browser does not support{" "}
+            <a
+              href="https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createDataChannel#Browser_compatibility"
+              rel="noreferrer noopener"
+            >
+              WebRTC Data Channels
+            </a>, which is required to use Hubs.
+          </div>
+        );
+      } else {
+        const reason = this.props.roomUnavailableReason || this.props.platformUnsupportedReason;
+        const exitSubtitleId = `exit.subtitle.${this.state.exited ? "exited" : reason}`;
+        subtitle = (
+          <div>
+            <FormattedMessage id={exitSubtitleId} />
+            <p />
+            {this.props.roomUnavailableReason && (
+              <div>
+                You can also <a href="/">create a new room</a>.
+              </div>
+            )}
           </div>
         );
       }
diff --git a/webpack.config.js b/webpack.config.js
index c0f8c88b3af3a6c2e43f7111f517841c4fcfec3c..bd561cbdaeab520fb6bd47dcf66f159c4a0b01bc 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -206,6 +206,12 @@ const config = {
         to: "favicon.ico"
       }
     ]),
+    new CopyWebpackPlugin([
+      {
+        from: "src/assets/images/hub-preview.png",
+        to: "hub-preview.png"
+      }
+    ]),
     // Extract required css and add a content hash.
     new ExtractTextPlugin({
       filename: "assets/stylesheets/[name]-[contenthash].css",