0

I am considering writing a Chrome extension in VueJS to totally change the apparence of a specific site.

Thus, I need to dynamically create an element, mount my VueJS app in it, and replace the body of the page with this rendered content.

I tested the dynamic creation of a container in a simple page, without Chrome extension, and it works great:

<html>
  <body>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
    <script>
      const app = new Vue({
        data: () => ({
          count: 0
        }),

        template: '<button v-on:click="count++">Clicked {{ count }} times</button>'
      });


      const body = document.getElementsByTagName('body')[0];
      let vueContainer = document.createElement('div')
      body.replaceWith(vueContainer);
      app.$mount(vueContainer);
    </script>
  </body>
</html>

This renders the VueJS app totally OK.

But then, when I create a Chrome extension, and put the same code in my script.js file, it actually replaces the content of the page with a blank page. The VueJS code is interpreted (if I add a console.log("something") in the mounted method of the VueJS app, it shows up).

// script.js

const app = new Vue({
  data: () => ({
    count: 0
  }),

  template: '<button v-on:click="count++">Clicked {{ count }} times</button>'
});

const body = document.getElementsByTagName('body')[0];
let vueContainer = document.createElement('div')
body.replaceWith(vueContainer);
app.$mount(vueContainer);
// manifest.json

{
  "name": "My extension",
  "description": "Blah",
  "version": "1.0",
  "manifest_version": 3,
  "content_scripts": [
    {
      "matches": ["https://www.mysite.fr/*"],
      "js": ["vue@2.6.12", "script.js"]
    }
  ]
}

It's like the extension prevents the rendered content to be displayed.

Actually, when inspecting the DOM, I have the confirmation that my VueJS app is fired: the div is replaced… but by a HTML comment instead of the rendered content:

<!---->

Any ideas? Thanks in advance!

user650108
  • 1,009
  • 1
  • 9
  • 18
  • `"vue@2.6.12"` does not look like a valid script. You should download vue bundle as a js file, put it into extension directory/package, and specify the actual correct name in `js`. If the script is fine but just the name is weird, try renaming it to .js anyway. – wOxxOm Apr 23 '21 at 11:27
  • Thanks for your comment wOxxOm, but that's not the problem: as I said, vue@2.6.12 is loaded OK and my VueJS app is executed, hence the output in console if I had a console.log in the mounted method. Seems more like a rendering issue due to the Chrome extension? – user650108 Apr 23 '21 at 12:12
  • Well, since it works in the popup, you can do the same by using `iframe` instead of `div` and rendering Vue inside that iframe, [example](https://stackoverflow.com/a/25100953). – wOxxOm Apr 23 '21 at 12:23
  • Well, it doesn't work either :( I edited my original post after confirming the app is actually executed, the DOM is updated, but instead of getting the rendered template, is just gets a comment: ``. Hence the blank page. That's strange… – user650108 Apr 23 '21 at 13:35
  • The iframe solution uses exactly the same html + scripts inside the iframe as your already working solution so it should work too. – wOxxOm Apr 23 '21 at 13:39

1 Answers1

0

OK, so I solved it thanks to the doc. Chrome extension will block any js tags within the templates.

So the only solution is to pass a pre-compiled template.

Using vue-cli, then building the app to have both scripts ans tags in js files, and then referencing it in the manifest.json file works!

user650108
  • 1,009
  • 1
  • 9
  • 18