diff --git a/src/assets/stylesheets/scene-ui.scss b/src/assets/stylesheets/scene-ui.scss
index bd3abf0a6d82cf898081da35c23add7ce692b024..42de9e2f194863d3ea37dd21d7104af060651ea4 100644
--- a/src/assets/stylesheets/scene-ui.scss
+++ b/src/assets/stylesheets/scene-ui.scss
@@ -95,6 +95,12 @@
 :local(.attribution) {
   font-size: 1.0em;
   white-space: wrap;
+
+  a {
+    font-size: 0.8em;
+    color: black;
+    pointer-events: auto;
+  }
 }
 
 :local(.screenshot) {
diff --git a/src/react-components/scene-ui.js b/src/react-components/scene-ui.js
index 2db97a04c5a0d56824f8b4677474b6ddb97540d9..314f6bf9149a6fe4baa12295cedd224db294f28c 100644
--- a/src/react-components/scene-ui.js
+++ b/src/react-components/scene-ui.js
@@ -20,7 +20,7 @@ class SceneUI extends Component {
     sceneId: PropTypes.string,
     sceneName: PropTypes.string,
     sceneDescription: PropTypes.string,
-    sceneAttribution: PropTypes.string,
+    sceneAttributions: PropTypes.object,
     sceneScreenshotURL: PropTypes.string
   };
 
@@ -73,6 +73,47 @@ class SceneUI extends Component {
       tweetText
     )}`;
 
+    let attributions;
+
+    const toAttributionSpan = a => {
+      if (a.url) {
+        const source = a.url.indexOf("sketchfab.com")
+          ? "on Sketchfab"
+          : a.url.indexOf("poly.google.com")
+            ? "on Google Poly"
+            : "";
+
+        return (
+          <span key={a.url}>
+            <a href={a.url} target="_blank" rel="noopener noreferrer">
+              {a.name} by {a.author} {source}
+            </a>&nbsp;
+          </span>
+        );
+      } else {
+        return (
+          <span key={`${a.name} ${a.author}`}>
+            {a.name} by {a.author}&nbsp;
+          </span>
+        );
+      }
+    };
+
+    if (this.props.sceneAttributions) {
+      if (!this.props.sceneAttributions.extras) {
+        attributions = (
+          <span>
+            <span>by {this.props.sceneAttributions.creator}</span>&nbsp;
+            <br />
+            {this.props.sceneAttributions.content && this.props.sceneAttributions.content.map(toAttributionSpan)}
+          </span>
+        );
+      } else {
+        // Legacy
+        attributions = <span>{this.props.sceneAttributions.extras}</span>;
+      }
+    }
+
     return (
       <IntlProvider locale={lang} messages={messages}>
         <div className={styles.ui}>
@@ -106,7 +147,7 @@ class SceneUI extends Component {
           </div>
           <div className={styles.info}>
             <div className={styles.name}>{this.props.sceneName}</div>
-            <div className={styles.attribution}>{this.props.sceneAttribution}</div>
+            <div className={styles.attribution}>{attributions}</div>
           </div>
           <div className={styles.spoke}>
             <div className={styles.madeWith}>made with</div>
diff --git a/src/scene.js b/src/scene.js
index 6f2f0732d0da231b0bebef56b8ce526326aa5ea4..4172e624771d7fbd3ca5ce217052023ed113c930 100644
--- a/src/scene.js
+++ b/src/scene.js
@@ -102,7 +102,7 @@ const onReady = async () => {
   remountUI({
     sceneName: sceneInfo.name,
     sceneDescription: sceneInfo.description,
-    sceneAttribution: sceneInfo.attribution,
+    sceneAttributions: sceneInfo.attributions,
     sceneScreenshotURL: sceneInfo.screenshot_url
   });
 };