Search code examples
javascriptvue.jsbrowser-extension

Have a multipage browser extension with vue


I have started my project using vite-plugin-web-extension

I have started a blank project with yarn create vite-plugin-web-extension and was able to load the extension in my chrome browser.

I would like to have a login page and another page that is accessible only if the user is logged in. I'm assuming that I would have to create a new popup - I might be completely wrong here as this is my first time I'm creating a browser extension.

I have created a page in src/pages/Login.vue:

<template>
  <div>
    <div>
      Login
    </div>
  </div>
</template>

Then I have created the src/login.ts:

import Popup from "./pages/Login.vue";
import { createApp } from "vue";

createApp(Popup).mount("body");

Then I have created my src/login.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Refodev - Login</title>
</head>

<body></body>

<script type="module" src="./login.ts"></script>
</html>

Then in my src/pages/Popup.vue I have added a link that when clicked will redirect to the Login.vue page:

<script lang="ts" setup>
  import browser from "webextension-polyfill";

  function onClickLogin(e: Event) {
    e.preventDefault();

    console.log(browser.action);
    browser.action.setPopup({ popup: 'login.html' })
  }
</script>

<template>
  <div>
    <a href="/login" @click.native="onClickLogin">
        login here
    </a>
  </div>
</template>

Unfortunately it's not redirecting the user to the popup. Is this the correct way to actually do this? Should I setup vue-router? If yes, I setup just like I would do in a normal project?

Thank you very much for the effort in creating this project.

EDIT

Attaching the output for when building the extension:

$ vite build --watch --mode development
vite v4.3.9 building for development...

watching for file changes...

build started...

Build Steps
  1. Building src/popup.html indvidually
  2. Building src/background.ts indvidually

Building src/popup.html (1/2)
vite v4.3.9 building for development...
✓ 15 modules transformed.
dist/src/popup.html   0.39 kB │ gzip:  0.27 kB
dist/popup.css        0.39 kB │ gzip:  0.25 kB
dist/src/popup.js    59.83 kB │ gzip: 23.07 kB
✓ built in 351ms

Building src/background.ts (2/2)
vite v4.3.9 building for development...

watching for file changes...

build started...
✓ 4 modules transformed.
dist/src/background.js  10.01 kB │ gzip: 2.98 kB
built in 60ms.

✓ All steps completed.

✓ 1 modules transformed.
dist/manifest.json  0.27 kB │ gzip: 0.18 kB
built in 1721ms.

Opening browser...
Done!

You can see that login.html is not being exported.


Solution

  • Yes, you should use Vue Router. This way the popup.html contains the entire Vue app, and you can route based on authentication as usual.

    Since it's a chrome extension, opening the popup will default to a single page (i.e. index.html) but you can redirect as needed within you Vue app based on extension storage/state.

    As far as I know, there's no way to conditionally load a different popup page based on state. So Vue routing is the way to go.