diff --git a/src/assets/stylesheets/profile.scss b/src/assets/stylesheets/profile.scss
index 4b01331d346967f8c3c5ca538f7fe4ab332ae205..3911b025f0cdba74825dc6173cd0dff5cd76a0f4 100644
--- a/src/assets/stylesheets/profile.scss
+++ b/src/assets/stylesheets/profile.scss
@@ -13,6 +13,11 @@
   z-index: 10;
   background-color: rgba(255, 255, 255, 0.95);
 
+
+  a {
+    cursor: pointer;
+  }
+
   :local(.logo) {
     width: 150px;
     position: absolute;
@@ -35,6 +40,15 @@
     .loading-panel {
       background: transparent;
     }
+
+    .custom-url-link {
+      position: absolute;
+      top: 10px;
+      right: 30px;
+      z-index: 100;
+      text-shadow: 0px 0px 6px #202020;
+      color: white;
+    }
   }
 
   :local(.avatar-selector) {
diff --git a/src/react-components/profile-entry-panel.js b/src/react-components/profile-entry-panel.js
index e4d02c70a4bb896816c44d8018aeae2da8ea0139..18df90851d2a5d6a1d923a09a52aba934d8e4ab3 100644
--- a/src/react-components/profile-entry-panel.js
+++ b/src/react-components/profile-entry-panel.js
@@ -6,6 +6,7 @@ import styles from "../assets/stylesheets/profile.scss";
 import classNames from "classnames";
 import hubLogo from "../assets/images/hub-preview-white.png";
 import { WithHoverSound } from "./wrap-with-audio";
+import { avatars } from "../assets/avatars/avatars";
 
 class ProfileEntryPanel extends Component {
   static propTypes = {
@@ -18,7 +19,7 @@ class ProfileEntryPanel extends Component {
   constructor(props) {
     super(props);
     const { displayName, avatarId } = this.props.store.state.profile;
-    this.state = { displayName, avatarId };
+    this.state = { displayName, avatarId, customMode: avatarId && avatarId.startsWith("http") };
     this.props.store.addEventListener("statechanged", this.storeUpdated);
   }
 
@@ -39,7 +40,8 @@ class ProfileEntryPanel extends Component {
         hasChangedName: hasChangedNowOrPreviously
       },
       profile: {
-        ...this.state
+        displayName: this.state.displayName,
+        avatarId: this.state.avatarId
       }
     });
     this.props.finished();
@@ -94,20 +96,46 @@ class ProfileEntryPanel extends Component {
               title={formatMessage({ id: "profile.display_name.validation_warning" })}
               ref={inp => (this.nameInput = inp)}
             />
-            <div className={styles.avatarSelectorContainer}>
-              <div className="loading-panel">
-                <div className="loader-wrap">
-                  <div className="loader">
-                    <div className="loader-center" />
+            {this.state.customMode ? (
+              <div className={styles.avatarSelectorContainer}>
+                <label htmlFor="#custom-avatar-url" className={styles.title}>
+                  Avatar GLTF/GLB{" "}
+                </label>
+                <input
+                  id="custom-avatar-url"
+                  type="url"
+                  className={styles.formFieldText}
+                  value={this.state.avatarId}
+                  onChange={e => this.setState({ avatarId: e.target.value })}
+                />
+                <div className={styles.links}>
+                  <a onClick={() => this.setState({ customMode: false, avatarId: "botdefault" })}>cancel</a>
+                </div>
+              </div>
+            ) : (
+              <div className={styles.avatarSelectorContainer}>
+                <div className="loading-panel">
+                  <div className="loader-wrap">
+                    <div className="loader">
+                      <div className="loader-center" />
+                    </div>
                   </div>
                 </div>
+                <iframe
+                  className={styles.avatarSelector}
+                  src={`/avatar-selector.html#avatar_id=${this.state.avatarId}`}
+                  ref={ifr => (this.avatarSelector = ifr)}
+                />
+                <a
+                  className="custom-url-link"
+                  onClick={() =>
+                    this.setState({ customMode: true, avatarId: avatars.find(a => a.id === this.state.avatarId).model })
+                  }
+                >
+                  options
+                </a>
               </div>
-              <iframe
-                className={styles.avatarSelector}
-                src={`/avatar-selector.html#avatar_id=${this.state.avatarId}`}
-                ref={ifr => (this.avatarSelector = ifr)}
-              />
-            </div>
+            )}
             <WithHoverSound>
               <input className={styles.formSubmit} type="submit" value={formatMessage({ id: "profile.save" })} />
             </WithHoverSound>
diff --git a/src/scene-entry-manager.js b/src/scene-entry-manager.js
index 0bc3548b3df4f68962cc48c93c8856b290ac1521..9e079415207ce8dbd6be5e864c4b00ef16f72b63 100644
--- a/src/scene-entry-manager.js
+++ b/src/scene-entry-manager.js
@@ -137,10 +137,10 @@ export default class SceneEntryManager {
   };
 
   _updatePlayerRigWithProfile = () => {
-    const displayName = this.store.state.profile.displayName;
+    const { avatarId, displayName } = this.store.state.profile;
     this.playerRig.setAttribute("player-info", {
       displayName,
-      avatarSrc: "#" + (this.store.state.profile.avatarId || "botdefault")
+      avatarSrc: avatarId && avatarId.startsWith("http") ? avatarId : `#${avatarId || "botdefault"}`
     });
     const hudController = this.playerRig.querySelector("[hud-controller]");
     hudController.setAttribute("hud-controller", { showTip: !this.store.state.activity.hasFoundFreeze });