diff --git a/front/src/components/audio/EmbedWizard.vue b/front/src/components/audio/EmbedWizard.vue
new file mode 100644
index 0000000000000000000000000000000000000000..7a50ffa54223a189d40cd91fbbe9f0e41b0814ee
--- /dev/null
+++ b/front/src/components/audio/EmbedWizard.vue
@@ -0,0 +1,80 @@
+<template>
+  <div>
+    <div class="ui form">
+      <div class="two fields">
+        <div class="field">
+          <div class="field">
+            <label for="embed-width"><translate>Widget width</translate></label>
+            <p><translate>Leave empty for a responsive widget</translate></p>
+            <input id="embed-width" type="number" v-model.number="width" min="0" step="10" />
+          </div>
+          <template v-if="type != 'track'">
+            <br>
+            <div class="field">
+              <label for="embed-height"><translate>Widget height</translate></label>
+              <input id="embed-height" type="number" v-model="height" :min="minHeight" max="1000" step="10" />
+            </div>
+          </template>
+        </div>
+        <div class="field">
+          <button @click="copy" class="ui right floated button"><translate>Copy</translate></button>
+          <label for="embed-width"><translate>Embed code</translate></label>
+          <p><translate>Copy/paste this code in your website HTML</translate></p>
+          <div class="ui hidden divider"></div>
+          <textarea ref="textarea":value="embedCode" rows="3" readonly>
+          </textarea>
+        </div>
+      </div>
+    </div>
+    <div class="preview">
+      <h3><translate>Preview</translate></h3>
+      <iframe :width="frameWidth" :height="height" scrolling="no" frameborder="no" :src="iframeSrc"></iframe>
+    </div>
+  </div>
+</template>
+
+<script>
+
+export default {
+  props: ['type', 'id'],
+  data () {
+    let d = {
+      width: null,
+      height: 150,
+      minHeight: 100
+    }
+    if (this.type === 'album') {
+      d.height = 330
+      d.minHeight = 250
+    }
+    return d
+  },
+  computed: {
+    iframeSrc () {
+      return this.$store.getters['instance/absoluteUrl'](
+        `/front/embed.html?&type=${this.type}&id=${this.id}`
+      )
+    },
+    frameWidth () {
+      if (this.width) {
+        return this.width
+      }
+      return '100%'
+    },
+    embedCode () {
+      let src = this.iframeSrc.replace(/&/g, '&amp;')
+      return `<iframe width="${this.frameWidth}" height="${this.height}" scrolling="no" frameborder="no" src="${src}"></iframe>`
+    }
+  },
+  methods: {
+    copy () {
+      this.$refs.textarea.select()
+      document.execCommand("Copy")
+    }
+  }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+</style>
diff --git a/front/src/components/federation/LibraryWidget.vue b/front/src/components/federation/LibraryWidget.vue
index ff73bb7a892d77d09969100e54e7137b6d15e0c4..abe993e4662a01cda6feb10f6f97d19bcdb26ea4 100644
--- a/front/src/components/federation/LibraryWidget.vue
+++ b/front/src/components/federation/LibraryWidget.vue
@@ -62,6 +62,7 @@ export default {
         self.nextPage = response.data.next
         self.isLoading = false
         self.libraries = response.data.results
+        self.$emit('loaded', self.libraries)
       }, error => {
         self.isLoading = false
         self.errors = error.backendErrors
diff --git a/front/src/components/library/Album.vue b/front/src/components/library/Album.vue
index 9a4adfafc1134d854e6267a68740e19f4c413649..6a3cfaa8ebf64fc87e51c36179b25b8bbc6b2ebd 100644
--- a/front/src/components/library/Album.vue
+++ b/front/src/components/library/Album.vue
@@ -37,6 +37,30 @@
             <i class="external icon"></i>
             <translate>View on MusicBrainz</translate>
           </a>
+          <template v-if="publicLibraries.length > 0">
+            <button
+              @click="showEmbedModal = !showEmbedModal"
+              class="ui button">
+              <i class="code icon"></i>
+              <translate>Embed</translate>
+            </button>
+            <modal :show.sync="showEmbedModal">
+              <div class="header">
+                <translate>Embed this album on your website</translate>
+              </div>
+              <div class="content">
+                <div class="description">
+                  <embed-wizard type="album" :id="album.id" />
+
+                </div>
+              </div>
+              <div class="actions">
+                <div class="ui deny button">
+                  <translate>Cancel</translate>
+                </div>
+              </div>
+            </modal>
+          </template>
         </div>
       </section>
       <template v-if="discs && discs.length > 1">
@@ -64,7 +88,7 @@
         <h2>
           <translate>User libraries</translate>
         </h2>
-        <library-widget :url="'albums/' + id + '/libraries/'">
+        <library-widget @loaded="libraries = $event" :url="'albums/' + id + '/libraries/'">
           <translate slot="subtitle">This album is present in the following libraries:</translate>
         </library-widget>
       </section>
@@ -79,6 +103,8 @@ import backend from "@/audio/backend"
 import PlayButton from "@/components/audio/PlayButton"
 import TrackTable from "@/components/audio/track/Table"
 import LibraryWidget from "@/components/federation/LibraryWidget"
+import EmbedWizard from "@/components/audio/EmbedWizard"
+import Modal from '@/components/semantic/Modal'
 
 const FETCH_URL = "albums/"
 
@@ -98,13 +124,17 @@ export default {
   components: {
     PlayButton,
     TrackTable,
-    LibraryWidget
+    LibraryWidget,
+    EmbedWizard,
+    Modal
   },
   data() {
     return {
       isLoading: true,
       album: null,
-      discs: []
+      discs: [],
+      libraries: [],
+      showEmbedModal: false
     }
   },
   created() {
@@ -129,6 +159,11 @@ export default {
         title: this.$gettext("Album")
       }
     },
+    publicLibraries () {
+      return this.libraries.filter(l => {
+        return l.privacy_level === 'everyone'
+      })
+    },
     wikipediaUrl() {
       return (
         "https://en.wikipedia.org/w/index.php?search=" +
diff --git a/front/src/components/library/Track.vue b/front/src/components/library/Track.vue
index 4aeecdf39dbf5355ccadaa1053899403119d57d6..d4127de1d719a0dd800d24de93956d1d35551aa1 100644
--- a/front/src/components/library/Track.vue
+++ b/front/src/components/library/Track.vue
@@ -55,6 +55,30 @@
             <i class="download icon"></i>
             <translate>Download</translate>
           </a>
+          <template v-if="publicLibraries.length > 0">
+            <button
+              @click="showEmbedModal = !showEmbedModal"
+              class="ui button">
+              <i class="code icon"></i>
+              <translate>Embed</translate>
+            </button>
+            <modal :show.sync="showEmbedModal">
+              <div class="header">
+                <translate>Embed this track on your website</translate>
+              </div>
+              <div class="content">
+                <div class="description">
+                  <embed-wizard type="track" :id="track.id" />
+
+                </div>
+              </div>
+              <div class="actions">
+                <div class="ui deny button">
+                  <translate>Cancel</translate>
+                </div>
+              </div>
+            </modal>
+          </template>
         </div>
       </section>
       <section class="ui vertical stripe center aligned segment">
@@ -144,7 +168,7 @@
         <h2>
           <translate>User libraries</translate>
         </h2>
-        <library-widget :url="'tracks/' + id + '/libraries/'">
+        <library-widget @loaded="libraries = $event" :url="'tracks/' + id + '/libraries/'">
           <translate slot="subtitle">This track is present in the following libraries:</translate>
         </library-widget>
       </section>
@@ -162,6 +186,7 @@ import TrackFavoriteIcon from "@/components/favorites/TrackFavoriteIcon"
 import TrackPlaylistIcon from "@/components/playlists/TrackPlaylistIcon"
 import LibraryWidget from "@/components/federation/LibraryWidget"
 import Modal from '@/components/semantic/Modal'
+import EmbedWizard from "@/components/audio/EmbedWizard"
 
 const FETCH_URL = "tracks/"
 
@@ -172,7 +197,8 @@ export default {
     TrackPlaylistIcon,
     TrackFavoriteIcon,
     LibraryWidget,
-    Modal
+    Modal,
+    EmbedWizard
   },
   data() {
     return {
@@ -181,7 +207,9 @@ export default {
       isLoadingLyrics: true,
       track: null,
       lyrics: null,
-      licenseData: null
+      licenseData: null,
+      libraries: [],
+      showEmbedModal: false
     }
   },
   created() {
@@ -224,6 +252,11 @@ export default {
     }
   },
   computed: {
+    publicLibraries () {
+      return this.libraries.filter(l => {
+        return l.privacy_level === 'everyone'
+      })
+    },
     labels() {
       return {
         title: this.$gettext("Track")