Skip to content
Advertisement

How to include vue app inside another vue app?

I’m currently requested to generate widget that will be included in different customers web sites.

Let’s say somthing like:

exemple

There is 2 constraintes:

  1. The use of iframe is forbidden
  2. The customers website could be done in whatever thecnology (PHP, React, ANgular, Vue.js, JQuery,…)

As the requested widget should be interactive, I wanted to develop it using javascript framwork (I thought about Vue.js).

However, I thought that this could lead to some conflicts (or even break customer’s website) for instance if the customer’s website is already use another version of Vue.js.

I spent several hours looking and thinking about a solution, but expect using an iframe I didn’t found anything…

=> Is there a way to include Vue.js apps inside another Vue.js app (or React, Angular, …) ?

Thanks in advance for your help.

Advertisement

Answer

Important edit:
since I wrote this answer, I discovered a simpler method to wrap an entire project as a single .js file, documented here.

If you need more control over when the app is instantiated and whether or not it should contain Vue, here’s the original answer (not claiming it’s better – i simply wrote it at a time I didn’t have any alternative, and it worked):


Orignal answer:

My current company typically delivers embedded apps in our clients’ webpages. Note: although the example below is written in .ts, it’s almost identical in .js.

After testing various methods (Vue’s quite flexible), here’s what we ended up doing:

The method is inspired by mapbox-gl‘s model, adapted to Vue.
The base principle is simple: export your entire app as a clean JS class (imported via a single script) and run

JavaScript

For this purpose, I typically create a someClass.ts file (which does the job main.ts normally does), but exports a class:

JavaScript

Note: Making this crystal clear: none of the above imports are necessary (i.e: axios, i18n, etc… – it’s just an example). Do whatever your main.ts (or main.js) is normally doing. Then create the Instance, inject config, export the class and any named exports you might need from Instance.

The above already does the job (if you build it using the build command specified below), but you’ll have to also adapt main.ts to import this class and render the app when serving:

JavaScript

And public/index.html looks like this:

JavaScript

The build command is:

JavaScript

Notice we’re exporting src/someClass.ts. You’ll end up with a file called SomeClass.umd.js.

Also, adding this setting to config.vue.js:

JavaScript

will enable you to init the class without .default() when you import it in the context page. without the above webpack option, you’d need to init it like this:

JavaScript

Everything else is pretty standard.

And now the context page only needs to import the .umd.js, instantiate app with

JavaScript

… and add one or more listeners on the rendered element.

The .umd.js export can be served from an external server and, obviously, can be imported from an npm package.

You don’t have to --inline-css and --inline-vue if it makes more sense to load them separately (i.e: Vue might already be present in context page). Also, often times I rely on libraries already present in the context page (you want to reuse as many libs as possible), using vue.config.js:

JavaScript

When you do this, remember to add a script pointing to lodash/jquery/whatever cdn in public/index.html, so it gets loaded when serving/developing, as it would in context page.

Finally, the demo.html (used to showcase the prod build), looks like this:

JavaScript

Of course, you’ll have to add all externals to it, before your app’s script (./SomeClass.umd.min.js), if you used any. Don’t defer them. The app expects them loaded in window by the time it inits.

As for conflicts, you shouldn’t have any. Vue is highly compatible across minors so you could simply use the context page’s Vue (instead of inlining it). Also, Vue 2 syntax is supposed to be fully compatible with Vue 3 (as in, you’d be able to run Vue 2 apps with Vue 3 without making any changes to them – we’ll see).

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement