Issue with Vue.js app display within Chrome extension

I have encountered an issue while trying to run a Vuejs app in a Chrome extension as a new tab. The app renders perfectly fine when running it from the dist/ folder using simplehttpserver dist/. However, when I attempt to load the dist folder as a Chrome Extension and open a new tab, the Vuejs app fails to render.

To build the app, I am using npm run build and then adding the files manifest.json and background.js into the dist/ folder.

Upon inspecting the element in the Chrome extension version, I noticed that the <div id="app"></div> is missing from the DOM, even though it exists in the index.html file after building the app.

Note: The Vuejs app I am attempting to use as a Chrome extension is the default example app created by vue init webpack ..

manifest.json

{
  "manifest_version": 2,
  "name": "Vuejs test extension",
  "description": "",
  "version": "0.0.0",

  "chrome_url_overrides": {
    "newtab": "index.html"
  },

  "browser_action": {
    "default_icon": "icon.png"
  },

  "permissions": [
    "tabs"
  ],

  "background": {
    "scripts": ["background.js"],
    "persistent": false
  }
}

background.js

chrome.browserAction.onClicked.addListener((function() {
    chrome.tabs.create({'url': "chrome://newtab"})
}));

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>Test vuejs app</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

Answer №1

I have discovered a simple and efficient solution.

It has been noted by many that the issue lies with Vue rendering templates at runtime. To accomplish this, Vue utilizes the eval() function which is typically restricted by Chrome extensions for security purposes.

To circumvent this limitation, you can insert the following line into your manifest.json:

"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"

However, it should be noted that this approach is not recommended as it exposes your extension to potential cross-site scripting vulnerabilities.

Alternatively, you can opt for Vue to render templates at compile time. This eliminates the need for invoking eval() on your templates.

A straightforward method to achieve template rendering at compile time is by configuring the Vue build to runtime during the project creation using vue init webpack.

This directive compels Vue to utilize pre-compiled templates as detailed in the following article:

This aligns perfectly with our objective of avoiding the use of the eval() function altogether.

Answer №2

If you're looking to create a chrome-extension with Vuejs, you can utilize the following boilerplate: this. Ensure that you have the vue-cli installed. If not, you can easily install it using `npm install -g @vue/cli`.

Once the vue-cli is installed, execute this command:

vue init kocal/vue-web-extension my-extension
. This will download and set up the Vuejs boilerplate template for a chrome-extension in your current directory. Proceed by navigating to the newly created directory and installing the dependencies using the command npm install.

Now that you've completed setting up the Vuejs app for your chrome-extension, keep in mind that it will initially open as a popup window. To make it visible in a new tab, some modifications are required, which I'll outline below.

  1. Start by accessing the src/manifest.json file and remove
    "default_popup": "popup/popup.html"
    from "browser_action".
  2. Next, go to the src/background.js file, delete the existing code, and replace it with the provided code snippet below.

    chrome.browserAction.onClicked.addListener(function (tab) {
        chrome.tabs.create(
            {
                url: chrome.extension.getURL('./popup/popup.html'),
            },
            function (tab) { }
        );
    });
    
  3. Proceed to run npm run build, which will generate the dist folder to serve as your extension folder. You can then load it into Chrome by selecting the 'Load unpacked' option in the Chrome extensions menu.

With these steps, you should be able to view the Vuejs app running in a new tab window by simply clicking on the extension icon.

If you encounter any issues or if the solution doesn't work as expected, please let me know so I can assist further.

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

Having issues with Next.js server-side rendering when integrating API functionality

"Not building properly" means that the project is not fully completing the build process. I've developed a simple blog project with dynamic SSR that pulls data from the Notion-API to generate static blog pages. Everything functions correctly ...

Managing both clicking and hovering events on a single element, ensuring that the popup modal remains open as long as it is being hovered over

After successfully implementing click and hover functionality on an element, I was able to position the popup relative to the mouse pointer based on a previous solution. However, I am now facing an issue where I want the popup modal to be fixed in a specif ...

Is it possible to use the .focus() event on an entire form in JQuery? If so, how

Take a look at this HTML snippet: <form ....> <textarea>....</textarea <input .... /> </form> I'm trying to set up a help section that appears when the user focuses on any form element, and disappears when they lose ...

Sorting through items based on several URL parameters

In an effort to be concise yet clear, I am working on an ecommerce website using Next.js and Shopify. This site features products that need to be filterable based on certain attributes. I retrieve products from the Shopify API, each with its own Product Ty ...

What is the best way to avoid the pipe symbol in jade formatting?

When working with jade, the pipe symbol (|) is utilized for displaying plain text. But what if you need to actually write it on the page? Is there a way to escape it in Jade? ...

Gaining entry to specialized assistance through an occasion

Having trouble accessing a custom service from a custom event. Every time the event is fired, the service reference turns out to be null. @Component({ selector: "my-component", template: mySource, legacy: { transclude: true } }) export class myComponent { ...

Vue.js component communication issue causing rendering problems

When it comes to the Parent component, I have this snippet of code: <todo-item v-for="(todo, index) in todos" :key="todo.id" :todo="todo" :index="index"> </todo-item> This piece simply loops through the todos array, retrieves each todo obj ...

A simple guide on passing a variable from Node.js to the view

Currently, I am delving into the world of Node.js and encountering a hurdle in sending a variable from app.js to index.html without relying on Jade or any other template engine. Below is my implementation in app.js: var express = require("express"); var ...

What is the best way to send an axios request in a Vue component to a route created by an Adonis controller?

My WidgetController.js file is responsible for handling CRUD operations on the database. Within this controller, there is a method/generator called * create (request, response) which returns widget attributes in a response and also inserts a new row into t ...

Change the name of a file to a name chosen by the user while uploading it to an

I'm a beginner when it comes to node.js and I'm facing an issue that I couldn't find a solution for despite looking into various related topics. My problem involves using Node.js on the server side to upload a file and rename it based on a ...

Is it necessary to include a back button when navigating through paginated tables?

Within my AngularJS application, I have implemented pagination on the user list page. This allows me to retrieve ten users at a time from the server, with each click loading another set of ten users on a new page. The user details are presented in a tabl ...

Automated tools and frameworks for the testing of website performance

Hello, I have a website that heavily relies on AJAX for server communication. I am looking to conduct performance and stress testing using automated scripts. Can you provide any suggestions or recommendations? I am specifically interested in the functiona ...

Rendering the page using ReactDOM.render

Just started with ReactJS, I'm struggling to figure out why my page isn't displaying anything - <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> ...

Securing Angular 2+: Safeguarding Server-Side Lazy Loaded Modules

In my Angular 2+ application, users input personal data that is then analyzed in a different section of the app restricted to authorized personnel. The challenge lies in preventing unauthorized individuals from gaining insight into the analysis process. We ...

Can you explain the relationship between HTML 5 Canvas coordinates and browser pixels?

When trying to use HTML 5 canvas as a drawing board in my application, I encountered an issue. The drawings appear at an offset from the mouse pointer. My method involves using the Jquery .offset function to determine the event's position on the canv ...

What is the best way to center align an element while having another element situated directly below it?

I want to create a grid of "clock" elements, with five clocks in each row. Below each clock, I'd like to display the DAY and DATE centered with the clock (day on top line, date below). Since I'm new to html/css, I appreciate your patience. Here&a ...

Parent page cannot access Nuxt.js global events emitted by pages inside iframes

I am currently in the process of developing a pattern library application that showcases components within iframe elements, accompanied by their corresponding HTML. My goal is to have the page containing the iframe automatically refresh and fetch the new H ...

Steps to transfer text from one input field to another by clicking a button using JavaScript

Hello, I am new to Javascript so please forgive me if my question seems silly. I have been tasked with creating a form containing two input fields and a button. When the button is clicked, the text entered in the first field should move to the second field ...

Technique for transferring information between properties of a class instance within an Express server's architecture

I am in the process of developing a monitoring server for a library using Express. My goal is to create different routers and routes, while also being able to access functions and variables from the monitor-server class. Currently, I have passed the ' ...

Fetching byte array from Spring Boot and transmitting it to Vue frontend

I am faced with a challenge involving functions that require reading an encoded image string from my MongoDB database, decoding it, and sending it to my Vue frontend for downloading. @GetMapping(path = "/signature/{signatureId}", produces = MediaType.IMAG ...