javascriptvue.jsaddthis

AddThis with Vue shares wrong links


So I have a page that uses AddThis for link sharing and Vue for rendering. Now, the page displays a list of links with multiple pages. On the first page all sharing works as expected, but on the second page, it uses the links from the first page.

An example to reproduce this:

new Vue({
  el: '#app',
  data: {
    pages: [
      [{
        url: 'http://google.com',
        title: 'Google'
      }],
      [{
        url: 'http://yahoo.com',
        title: 'Yahoo'
      }]
    ],
    currentPage: 0
  },
  computed: {
    items() {
      return this.pages[this.currentPage]
    }
  },
  methods: {
    switchPage() {
      if (this.currentPage === 0) {
        this.currentPage = 1;
      } else {
        this.currentPage = 0;
      }
    }
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <div class="sharer" v-for="item in items">
    <div class="addthis_inline_share_toolbox" :data-url="item.url" :data-title="item.title">{{ item.title }}</div>
  </div>
  <button @click="switchPage">Switch pages</button>
</div>

<script src="https://s7.addthis.com/js/300/addthis_widget.js#pubid=ra-57f620a4f185d54b"></script>

When on the first page, AddThis correctly shares the Google homepage. But when on the second page, it doesn't pick up the data-* tags for sharing Yahoo.

Note: You can't really run the StackOverflow snippet here because AddThis wants to access cookies which the sandboxed iframe forbids. A running version can also be found at https://jsfiddle.net/d1az3qb3/3/. Please remember to disable ad-blockers to let AddThis load.

What I already tried

(Both directly and in this.$nextTick(() => …))

Question

Is AddThis just broken, is it incompatible with Vue or is there a way to make it work?


Solution

  • So, after hours of digging into this, it seems to work after destroying and re-initializing all AddThis layers (using the SmartLayer API) like this:

    new Vue({
      el: '#app',
      data: {
        pages: [
          [{
            url: 'http://google.com',
            title: 'Google'
          }],
          [{
            url: 'http://yahoo.com',
            title: 'Yahoo'
          }]
        ],
        currentPage: 0
      },
      computed: {
        items() {
          return this.pages[this.currentPage]
        }
      },
      methods: {
        switchPage() {
          if (this.currentPage === 0) {
            this.currentPage = 1;
          } else {
            this.currentPage = 0;
          }
    
          this.$nextTick(() => {
            // The interesting bit:
            const destroyLayers = layers => layers.destroy();
            destroyLayers.pi = true;  // Somehow needed by AddThis
    
            addthis.layers(destroyLayers);
            addthis.layers.refresh();
          });
        }
      }
    })
    <script src="https://unpkg.com/vue"></script>
    
    <div id="app">
      <div class="sharer" v-for="item in items">
        <div class="addthis_inline_share_toolbox_ctwk" :data-url="item.url" :data-title="item.title">{{ item.title }}</div>
      </div>
      <button @click="switchPage">Switch pages</button>
    </div>
    
    <script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-57f620a4f185d54b"></script>

    For a completely functional JSFiddle, see https://jsfiddle.net/msiemens/82ysztk9/1/