diff --git a/src/react-components/photo-message.js b/src/react-components/photo-message.js
new file mode 100644
index 0000000000000000000000000000000000000000..ac4cfbceb03b7b7b339364b7b1293a2e66effd7d
--- /dev/null
+++ b/src/react-components/photo-message.js
@@ -0,0 +1,44 @@
+import React from "react";
+import PropTypes from "prop-types";
+
+import styles from "../assets/stylesheets/presence-log.scss";
+import classNames from "classnames";
+
+import { share } from "../utils/share";
+import { getLandingPageForPhoto } from "../utils/phoenix-utils";
+
+export default function PhotoMessage({ name, body: { src: url }, className, maySpawn, hubId }) {
+  const landingPageUrl = getLandingPageForPhoto(url);
+  const onShareClicked = share.bind(null, {
+    url: landingPageUrl,
+    title: `Taken in #hubs, join me at https://hub.link/${hubId}`
+  });
+  return (
+    <div className={className}>
+      {maySpawn && <button className={classNames(styles.iconButton, styles.share)} onClick={onShareClicked} />}
+      <div className={styles.mediaBody}>
+        <span>
+          <b>{name}</b>
+        </span>
+        <span>
+          {"took a "}
+          <b>
+            <a href={landingPageUrl} target="_blank" rel="noopener noreferrer">
+              photo
+            </a>
+          </b>.
+        </span>
+      </div>
+      <a href={landingPageUrl} target="_blank" rel="noopener noreferrer">
+        <img src={url} />
+      </a>
+    </div>
+  );
+}
+PhotoMessage.propTypes = {
+  name: PropTypes.string,
+  maySpawn: PropTypes.bool,
+  body: PropTypes.object,
+  className: PropTypes.string,
+  hubId: PropTypes.string
+};
diff --git a/src/react-components/presence-log.js b/src/react-components/presence-log.js
index 88f411b8f278256a50b399869c83375c06cf3427..4426ac46e1e86d22e82b01de4f59152bb8b2184f 100644
--- a/src/react-components/presence-log.js
+++ b/src/react-components/presence-log.js
@@ -3,51 +3,9 @@ import PropTypes from "prop-types";
 import styles from "../assets/stylesheets/presence-log.scss";
 import classNames from "classnames";
 import { FormattedMessage } from "react-intl";
-import ChatMessage from "./chat-message";
-import { share } from "../utils/share";
-
-function SpawnPhotoMessage({ name, body: { src: url }, className, maySpawn, hubId }) {
-  let landingPageUrl = new URL(url);
-  const [hostname, port] = process.env.RETICULUM_SERVER.split(":");
-  console.log(hostname, port, landingPageUrl.port);
-  landingPageUrl.hostname = hostname;
-  if (port) landingPageUrl.port = port;
-  landingPageUrl.pathname = landingPageUrl.pathname.replace(".png", ".html");
-  landingPageUrl = landingPageUrl.toString();
 
-  const onShareClicked = share.bind(null, {
-    url: landingPageUrl,
-    title: `Taken in #hubs, join me at https://hub.link/${hubId}`
-  });
-  return (
-    <div className={className}>
-      {maySpawn && <button className={classNames(styles.iconButton, styles.share)} onClick={onShareClicked} />}
-      <div className={styles.mediaBody}>
-        <span>
-          <b>{name}</b>
-        </span>
-        <span>
-          {"took a "}
-          <b>
-            <a href={landingPageUrl} target="_blank" rel="noopener noreferrer">
-              photo
-            </a>
-          </b>.
-        </span>
-      </div>
-      <a href={landingPageUrl} target="_blank" rel="noopener noreferrer">
-        <img src={url} />
-      </a>
-    </div>
-  );
-}
-SpawnPhotoMessage.propTypes = {
-  name: PropTypes.string,
-  maySpawn: PropTypes.bool,
-  body: PropTypes.object,
-  className: PropTypes.string,
-  hubId: PropTypes.string
-};
+import ChatMessage from "./chat-message";
+import PhotoMessage from "./photo-message";
 
 export default class PresenceLog extends Component {
   static propTypes = {
@@ -100,7 +58,7 @@ export default class PresenceLog extends Component {
         );
       case "spawn": {
         return (
-          <SpawnPhotoMessage
+          <PhotoMessage
             key={e.key}
             name={e.name}
             className={classNames(entryClasses, styles.media)}
diff --git a/src/scene-entry-manager.js b/src/scene-entry-manager.js
index ed86791042774c42b6e1a7d0440e3ad64090d028..461f42107a6c25daa5c740a6dd2ce25a3b9b09c1 100644
--- a/src/scene-entry-manager.js
+++ b/src/scene-entry-manager.js
@@ -259,7 +259,6 @@ export default class SceneEntryManager {
     });
 
     this.scene.addEventListener("photo_taken", e => {
-      console.log(e);
       this.hubChannel.sendMessage({ src: e.detail }, "spawn");
     });
   };
diff --git a/src/utils/phoenix-utils.js b/src/utils/phoenix-utils.js
index 19619599af4803c4d537b764888fb4de6b21491f..5d5307db881d1f8be8415908d04478d83ebb43ad 100644
--- a/src/utils/phoenix-utils.js
+++ b/src/utils/phoenix-utils.js
@@ -43,3 +43,8 @@ export function getReticulumFetchUrl(path) {
     return path;
   }
 }
+
+export function getLandingPageForPhoto(photoUrl) {
+  const parsedUrl = new URL(photoUrl);
+  return getReticulumFetchUrl(parsedUrl.pathname.replace(".png", ".html") + parsedUrl.search);
+}
diff --git a/src/utils/share.js b/src/utils/share.js
index 80cf4ed02bb8ec603a359759b50fd407fb205cae..e563431ff06fd7a77ba5a8b1feedff85ba211dfb 100644
--- a/src/utils/share.js
+++ b/src/utils/share.js
@@ -1,3 +1,6 @@
+/**
+ * Wraps navigator.share with a fallback to twitter for unsupported browsers
+ */
 export function share(opts) {
   if (navigator.share) {
     return navigator.share(opts);