What is the process for embedding a Vue app within another Vue app?

I have been tasked with creating a widget that will be integrated into various customers' websites.

Think about something like this:

https://i.sstatic.net/3uKwL.png

There are 2 constraints:

  1. The use of iframes is not allowed
  2. The customers' websites could be built using any technology (PHP, React, Angular, Vue.js, JQuery,...)

Since the widget needs to be interactive, I planned on developing it using a javascript framework (I was considering Vue.js).

However, I realized that this might cause conflicts (or even break the customer's website) if they are already using a different version of Vue.js, for example.

I have spent hours searching for a solution, but without resorting to using an iframe, I haven't found anything...

=> Is there a way to embed Vue.js applications within another Vue.js app (or React, Angular, etc.)?

Thank you in advance for your assistance.

Answer №1

Important update:
After writing the initial answer, I came across a more straightforward approach to bundle an entire project into a single .js file, which is detailed here.

If you require additional control over app initialization and Vue integration, here is the original response (not claiming superiority - it was just written when no alternatives were available):


Original response:

At my current company, we typically deploy embedded apps on our clients' websites. Note: while the example below is in .ts, it's almost identical to working with .js.

After experimenting with different methods (Vue being quite versatile), this is the approach we settled on:

The technique takes inspiration from mapbox-gl's model, modified for use with Vue.
The basic idea is simple: export your entire app as a clean JS class (imported via a single script) and then initiate it using

new SomeClass(selector, config);

For this purpose, I usually create a file called someClass.ts (performing tasks similar to what main.ts does normally), but exporting a class instead:

// code snippet not included for brevity
// rest of the content remains unchanged

Answer №2

Here's my approach using Vue3 and Vite:

Check out the example demo here

1. Simplify the main.ts (main.js)

View commit

Avoid creating and mounting the App in main.ts. Simply import and export it.

// /src/main.ts
import './assets/main.css'
import App from './App.vue'

export { App }

2. Adjust your dev index.html

View commit

Since main.ts is now passive, manually trigger app creation and mount it in your dev index.html. This step also applies when integrating the library into another app.

<!-- /index.html -->
<body>
  <div id="app"></div>

  <script type="module">
    import { createApp } from 'vue';
    import { App as VueLibExample } from '/src/main.ts';

    createApp(VueLibExample).mount('#app');
  </script>
</body>

Use an alias to prevent conflicts with other imported apps.

3. Building the library in mode

View commit

The key concept is to "build your app using library mode". Refer to Vite documentation for detailed steps on setting up vite.config.js and package.json.

Essentially, this is how my vite.config.js looks:

// vite.config.js
import { fileURLToPath, URL } from 'node:url'

// Other configuration details...

Make sure to include or exclude dependencies like 'vue' as needed but I recommend including to avoid version conflicts.

This is my package.json:

{
  // Package details...
}

To build the library:

> yarn build
yarn run v1.22.21

// Build output info...

4. Integrating the library in an HTML page

View commit

Once you have the exported files, integrate them in any HTML web page like this:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    
    // Other head elements...
  </head>
  <body>
    <div id="the-div"></div>

    // Script imports and app mounting...
  </body>
</html>

Note the special handling of importing CSS styles and libraries, as expected in the library JS.

Answer №3

If you want to include your Vue widget on a different website, you can achieve this using JavaScript. I successfully integrated my Vue widget into another website by following these steps:

   const insertWidget = () => new Promise((resolve, reject) => {
       let element = document.createElement("div")
       element.setAttribute("id", "widgetToAdd");
       document.body.appendChild(element);
       let app = new Vue({
         el: "#widgetToAdd",
         template: `<div>YOUR COMPONENTS</div>`
       })
       resolve(app);
    })

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Executing a JavaScript function using document.write()

When I try to click on the SWF part1 links within the document.write() function in order to call the openswf function, nothing happens. Here is my code: <html> <a href="#" onclick="Popup();">show popup</a> <script> functio ...

Create geometric shapes on Google Maps version 2

Can anyone guide me on how to draw a polygon on Google Maps with user-input coordinates? I have two input fields for latitude and longitude, and when the user clicks the button, I want the polygon to be drawn. The code I currently have doesn't seem to ...

Customize the color of each individual column in DotNet.HighCharts by setting unique colors for

Can DotNet.HighCharts be used to create a chart where each column is a unique color? ...

Having trouble with the addEventListener function not working on a vanilla JS form?

I'm struggling to get a form working on a simple rails project. The idea is to collect a name and date from the form and display them on the same page using JS. Later, I'll process this information to determine if it's your birthday and cal ...

Padding the body of a single-page Angular application to ensure proper spacing and

How do I add padding to the body of a template in an angular ng-app? Where is the best place to include CSS for a ng-app rendered template? please refer to this fiddle for an example https://jsfiddle.net/aghsqnpa/ div.ngview { padding: 25px 50px 75p ...

Having trouble setting up the rootReducer using combineReducers

import { combineReducers } from 'redux'; import { reducers } from './reducers'; import { IAppAction } from './action'; import { routerReducer } from 'react-router-redux'; import { IAppState } from './state/app-s ...

Is it possible to achieve dynamic updating in Angular without utilizing ng-repeat? (with the use of Firebase)

Is there a way to dynamically update the DOM without utilizing ng-repeat in your template? It appears that when using ng-repeat to load a list of objects, any additions or deletions from the database automatically reflect in the DOM. However, if I simply u ...

Converting a local Node.js server to an online server: A step-by-step guide

Currently working on a game for my school project. Originally designed to be an online multiplayer game, but have only been able to test it locally so far. Need help figuring out how to modify my server code to make it functional as a legitimate online ser ...

Using conditional routing for nested routes in VueJS

Is there a way to conditionally redirect a children route? I've experimented with various methods but haven't had any success. Currently, I am using a state from the store as the condition to redirect the children routes. I have exported my stor ...

When a user enters their ID, I endeavor to generate a personalized visiting card using canvas

I am currently working on a project where I need to generate a personalized visiting card based on input data. The idea is to iterate over an object and retrieve the relevant information upon button click, displaying it on a canvas element. Initially, my p ...

Adjusting hyperlinks placement based on window size changes using jQuery

On resizing the screen, I am moving the sub-nav links to the '#MoreList' It works well initially, but when the window is expanded again, the links remain in the #MoreList instead of going back to their original positions if there is enough space ...

Issue encountered with Fabric js: Unable to apply pattern fill to a group of rectangles

Greetings, I am in need of some assistance with a coding issue. I have a for loop that generates and adds multiple rectangles to a fabric js canvas. To set a texture for each rectangle, I am using the following code snippet. var rect = new fabric.Rect( ...

more efficient method for gathering information and refreshing a database

Presented here is a method for form submission. In reality, there are many more text inputs to consider. While everything functions properly, I am seeking a more concise approach, especially on the server side. This is due to the fact that the data-col ...

What could be the reason for this script not functioning properly and...?

Here is some HTML code: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" conte ...

What is the method for implementing two-way binding on a checkbox in Angular?

Within my accordion, I have a series of options in the form of checkboxes. Users are able to select these checkboxes, but I am seeking a way to pre-select certain checkboxes based on specific conditions. The challenge arises when these conditions are deter ...

How can I configure the Google Chrome script debugger to pause on exceptions?

Is there a way to automatically interrupt the program when an exception is encountered? ...

Tips for handling date type input to accommodate both JSON format and date format within AngularJS

I have a RESTful service that both produces and consumes JSON objects. { firstName: "Alex", lastName: "Ross", studentGroup: { groupId: 1, groupName: "java 15-1" }, admissionDate: "2015-03-25", status: { statusId: 3, statusName: "expelled" }, term: { termI ...

Steps for embedding the code into your website

I'm facing an issue with integrating a .jsx file into my website. I tried testing it on a single-page demo site, but nothing is showing up. Can someone guide me through the steps to successfully integrate it onto my site? I've also attached the . ...

Exploring the use of callbacks in React closures

After diving into a React related article, I delved deeper into discussions about closures and callbacks, checking out explanations on these topics from Stack Overflow threads like here, here, and here. The React article presented an example involving thr ...

Creating an associative array in javascript: A step-by-step guide

I require an array to be structured in the following manner: {"3": {"label":"All i want for christmas", "song":"Alliw_1405399165.mp3", "name":"All i want for christmas"}, "4": {"label":"Call your girlfriend robyn clip", "song":"Gang ...