diff --git a/src/assets/translations.data.json b/src/assets/translations.data.json
index c61b991c4bf080b0044701f4e853f1c8712a1936..0281dcd9f8d798366a072898e13230e3dc120faf 100644
--- a/src/assets/translations.data.json
+++ b/src/assets/translations.data.json
@@ -10,17 +10,17 @@
     "entry.desktop-screen": "Screen",
     "entry.mobile-screen": "Phone",
     "entry.mobile-safari": "Safari",
-    "entry.generic-prefix": "Enter with ",
-    "entry.generic-medium": "PC VR",
+    "entry.generic-prefix": " ",
+    "entry.generic-medium": "Connected Headset",
     "entry.generic-subtitle-desktop": "Oculus or SteamVR",
     "entry.gearvr-prefix": "Enter on ",
     "entry.gearvr-medium": "Gear VR",
     "entry.choose-device": "Choose Device",
-    "entry.device-prefix-desktop": "Use a ",
-    "entry.device-prefix-mobile": "Use a ",
+    "entry.device-prefix-desktop": " ",
+    "entry.device-prefix-mobile": " ",
     "entry.device-medium": "Mobile Headset",
-    "entry.device-subtitle-desktop": "Standalone or Phone Clip-in",
-    "entry.device-subtitle-mobile": "Standalone or Phone Clip-in",
+    "entry.device-subtitle-desktop": "Standalone or Mobile VR",
+    "entry.device-subtitle-mobile": "Standalone or Mobile VR",
     "entry.device-subtitle-vr": "Phone or PC",
     "entry.cardboard": "Enter on Google Cardboard",
     "entry.daydream-prefix": "Enter on ",
@@ -84,12 +84,12 @@
     "link.in_your_browser": "In your headset's browser, go to:",
     "link.enter_code": "Then, enter this one-time link code:",
     "link.do_not_close": "Keep this open to use this code.",
-    "link.connect_headset": "Connect Mobile Headset",
+    "link.connect_headset": "Link VR Headset",
     "link.cancel": "cancel",
     "invite.enter_via": "Enter via ",
     "invite.tweet": "tweet",
     "invite.and_enter_code": " with code:",
-    "invite.or_visit": "or visit",
+    "invite.or_visit": "or share permalink",
     "spoke.primary_tagline": "make your space",
     "spoke.secondary_tagline": "Create 3D social scenes for ",
     "spoke.thank_you": "Thank you for downloading Spoke!",
diff --git a/src/hub.js b/src/hub.js
index ec589e2da5eb2acb8b7e31df4c63c9d29a1723df..9685b24749ceb07f42b8afa778469b048a0a85b8 100644
--- a/src/hub.js
+++ b/src/hub.js
@@ -257,7 +257,7 @@ async function handleHubChannelJoined(entryManager, hubChannel, data) {
 
   document
     .querySelector("#hud-hub-entry-link")
-    .setAttribute("text", { value: `hub.link/${hub.entry_code}`, width: 1.1, align: "center" });
+    .setAttribute("text", { value: `hub.link/${hub.hub_id}`, width: 1.1, align: "center" });
 
   scene.setAttribute("networked-scene", {
     room: hub.hub_id,
diff --git a/src/link.js b/src/link.js
index 401fe54d9b8b9bd91df1c2140257710502a23add..7f803b75a780d22bd85e51f6902806efebea1b5e 100644
--- a/src/link.js
+++ b/src/link.js
@@ -6,6 +6,7 @@ import LinkRoot from "./react-components/link-root";
 import LinkChannel from "./utils/link-channel";
 import { connectToReticulum } from "./utils/phoenix-utils";
 import Store from "./storage/store";
+import { detectInHMD } from "./utils/vr-caps-detect.js";
 
 registerTelemetry();
 
@@ -17,4 +18,7 @@ const linkChannel = new LinkChannel(store);
 
 linkChannel.setSocket(socket);
 
-ReactDOM.render(<LinkRoot store={store} linkChannel={linkChannel} />, document.getElementById("link-root"));
+ReactDOM.render(
+  <LinkRoot store={store} linkChannel={linkChannel} showHeadsetLinkOption={detectInHMD()} />,
+  document.getElementById("link-root")
+);
diff --git a/src/react-components/invite-dialog.js b/src/react-components/invite-dialog.js
index aa5c511bc6da6f8b41c1d08222ea4d0fec7eb512..414194081d417d6185cd1041bdb1ed1a7be355ab 100644
--- a/src/react-components/invite-dialog.js
+++ b/src/react-components/invite-dialog.js
@@ -15,6 +15,7 @@ function pad(num, size) {
 export default class InviteDialog extends Component {
   static propTypes = {
     entryCode: PropTypes.number,
+    hubId: PropTypes.string,
     allowShare: PropTypes.bool,
     onClose: PropTypes.func
   };
@@ -42,11 +43,11 @@ export default class InviteDialog extends Component {
     const { entryCode } = this.props;
 
     const entryCodeString = pad(entryCode, 6);
-    const shareShortLink = `hub.link/${entryCodeString}`;
-    const shareFullLink = [location.protocol, "//", location.host, location.pathname].join("");
+    const shortLinkText = `hub.link/${this.props.hubId}`;
+    const shortLink = "https://" + shortLinkText;
 
     const tweetText = `Join me now in #hubs!`;
-    const tweetLink = `https://twitter.com/share?url=${encodeURIComponent(shareFullLink)}&text=${encodeURIComponent(
+    const tweetLink = `https://twitter.com/share?url=${encodeURIComponent(shortLink)}&text=${encodeURIComponent(
       tweetText
     )}`;
 
@@ -74,15 +75,15 @@ export default class InviteDialog extends Component {
           <FormattedMessage id="invite.or_visit" />
         </div>
         <div className={styles.domain}>
-          <input type="text" readOnly onFocus={e => e.target.select()} value={shareShortLink} />
+          <input type="text" readOnly onFocus={e => e.target.select()} value={shortLinkText} />
         </div>
         <div className={styles.buttons}>
-          <button className={styles.linkButton} onClick={this.copyClicked.bind(this, "https://" + shareShortLink)}>
+          <button className={styles.linkButton} onClick={this.copyClicked.bind(this, shortLink)}>
             <span>{this.state.copyButtonActive ? "copied!" : "copy"}</span>
           </button>
           {this.props.allowShare &&
             navigator.share && (
-              <button className={styles.linkButton} onClick={this.shareClicked.bind(this, shareFullLink)}>
+              <button className={styles.linkButton} onClick={this.shareClicked.bind(this, shortLink)}>
                 <span>{this.state.shareButtonActive ? "sharing..." : "share"}</span>
               </button>
             )}
diff --git a/src/react-components/link-root.js b/src/react-components/link-root.js
index 5253de0130b73f10d7e71ada313fa01057e0aaf1..be652f7b18d42a88f9cd9594cecdf46074c7e7b0 100644
--- a/src/react-components/link-root.js
+++ b/src/react-components/link-root.js
@@ -20,7 +20,8 @@ class LinkRoot extends Component {
   static propTypes = {
     intl: PropTypes.object,
     store: PropTypes.object,
-    linkChannel: PropTypes.object
+    linkChannel: PropTypes.object,
+    showHeadsetLinkOption: PropTypes.bool
   };
 
   state = {
@@ -178,16 +179,18 @@ class LinkRoot extends Component {
               </div>
 
               <div className={styles.enteredFooter}>
-                {!this.state.isAlphaMode && (
-                  <img onClick={() => this.toggleMode()} src={HeadsetIcon} className={styles.headsetIcon} />
-                )}
-                {!this.state.isAlphaMode && (
-                  <span>
-                    <a href="#" onClick={() => this.toggleMode()}>
-                      <FormattedMessage id="link.linking_a_headset" />
-                    </a>
-                  </span>
-                )}
+                {!this.state.isAlphaMode &&
+                  this.props.showHeadsetLinkOption && (
+                    <img onClick={() => this.toggleMode()} src={HeadsetIcon} className={styles.headsetIcon} />
+                  )}
+                {!this.state.isAlphaMode &&
+                  this.props.showHeadsetLinkOption && (
+                    <span>
+                      <a href="#" onClick={() => this.toggleMode()}>
+                        <FormattedMessage id="link.linking_a_headset" />
+                      </a>
+                    </span>
+                  )}
               </div>
             </div>
 
@@ -208,15 +211,19 @@ class LinkRoot extends Component {
                   {d}
                 </button>
               ))}
-              <button
-                className={classNames(styles.keypadButton, styles.keypadToggleMode)}
-                onTouchStart={() => this.toggleMode()}
-                onClick={() => {
-                  if (!hasTouchEvents) this.toggleMode();
-                }}
-              >
-                {this.state.isAlphaMode ? "123" : "ABC"}
-              </button>
+              {this.props.showHeadsetLinkOption ? (
+                <button
+                  className={classNames(styles.keypadButton, styles.keypadToggleMode)}
+                  onTouchStart={() => this.toggleMode()}
+                  onClick={() => {
+                    if (!hasTouchEvents) this.toggleMode();
+                  }}
+                >
+                  {this.state.isAlphaMode ? "123" : "ABC"}
+                </button>
+              ) : (
+                <div />
+              )}
               {!this.state.isAlphaMode && (
                 <button
                   disabled={this.state.entered.length === this.maxAllowedChars()}
diff --git a/src/react-components/ui-root.js b/src/react-components/ui-root.js
index 73c2a1e871da4c1f4185daf1a85efaaaac80eb62..153bd64b309abddc14cea0165aeab6cad3f5f3c6 100644
--- a/src/react-components/ui-root.js
+++ b/src/react-components/ui-root.js
@@ -553,7 +553,7 @@ class UIRoot extends Component {
   };
 
   onMiniInviteClicked = () => {
-    const link = "https://hub.link/" + this.props.hubEntryCode;
+    const link = "https://hub.link/" + this.props.hubId;
 
     this.setState({ miniInviteActivated: true });
     setTimeout(() => {
@@ -977,7 +977,7 @@ class UIRoot extends Component {
                       ? navigator.share
                         ? "sharing..."
                         : "copied!"
-                      : "hub.link/" + this.props.hubEntryCode}
+                      : "hub.link/" + this.props.hubId}
                   </span>
                 </button>
               )}
@@ -990,6 +990,7 @@ class UIRoot extends Component {
               <InviteDialog
                 allowShare={!this.props.availableVREntryTypes.isInHMD}
                 entryCode={this.props.hubEntryCode}
+                hubId={this.props.hubId}
                 onClose={() => this.setState({ showInviteDialog: false })}
               />
             )}
diff --git a/src/utils/vr-caps-detect.js b/src/utils/vr-caps-detect.js
index d5ad87eff808d1cb528c76b068de0c855d0bb3a0..fc2737ad41519798326d1f2ce6cec57e5a8e5b23 100644
--- a/src/utils/vr-caps-detect.js
+++ b/src/utils/vr-caps-detect.js
@@ -22,6 +22,11 @@ function isMaybeDaydreamCompatibleDevice(ua) {
 // that can be entered into as a "generic" entry flow.
 const GENERIC_ENTRY_TYPE_DEVICE_BLACKLIST = [/cardboard/i];
 
+export function detectInHMD() {
+  const isOculusBrowser = /Oculus/.test(navigator.userAgent);
+  return isOculusBrowser;
+}
+
 // Tries to determine VR entry compatibility regardless of the current browser.
 //
 // For each VR "entry type", returns VR_DEVICE_AVAILABILITY.yes if that type can be launched into directly from this browser
@@ -45,7 +50,6 @@ const GENERIC_ENTRY_TYPE_DEVICE_BLACKLIST = [/cardboard/i];
 export async function getAvailableVREntryTypes() {
   const ua = navigator.userAgent;
   const isSamsungBrowser = browser.name === "chrome" && /SamsungBrowser/.test(ua);
-  const isOculusBrowser = /Oculus/.test(ua);
 
   // This needs to be kept up-to-date with the latest browsers that can support VR and Hubs.
   // Checking for navigator.getVRDisplays always passes b/c of polyfill.
@@ -63,7 +67,9 @@ export async function getAvailableVREntryTypes() {
     : VR_DEVICE_AVAILABILITY.no;
 
   const displays = isWebVRCapableBrowser ? await navigator.getVRDisplays() : [];
-  const isInHMD = isOculusBrowser;
+
+  const isOculusBrowser = /Oculus/.test(ua);
+  const isInHMD = detectInHMD();
 
   const screen = isInHMD
     ? VR_DEVICE_AVAILABILITY.no