Chrome Extension (Vue 3 + Vue Router + Typescript + Vite + TailwindCSS)



Background

Hey! To write the extension, I will use:

Start 🚀

To create a new project, run the command in the console:

npm init vite@latest chrome-extension -- --template vue-ts

TailwindCSS

To install TailwindCSS:

npm install -D tailwindcss@latest postcss@latest autoprefixer@latest

npx tailwindcss init -p

Updates tailwind.config.js:

module.exports = {
  purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

In the project I will use SASS to install it along with TailwindCSS, execute the following commands:

npm install postcss-import

Updates postcss.config.js:

module.exports = {
  plugins: [
    require('postcss-import'),
    require('tailwindcss'),
    require('autoprefixer'),
  ]
}

SASS

Install SASS with the command:

npm i -D sass

Create a main.scss file in the assets/scss folder with the following content:

@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

html {
    body {
        #app {
            height: 100%;
            width: 100%;
            overflow-x: hidden;
        }
        &.popup {
            width: 357px;
            min-height: 600px;
            height: 600px;
            max-height: 600px;
        }
    }
}

Connect the main.scss into the main.ts file

import './assets/scss/main.scss'

Vue Router (vite-plugin-vue-layouts + vite-plugin-pages)

To install, run the command:

npm i -S vue-router@4.x vite-plugin-vue-layouts vite-plugin-pages

Updates main.ts
import { createApp } from 'vue'
import { createRouter, createWebHashHistory } from 'vue-router'
import generatedRoutes from 'virtual:generated-pages'
import { setupLayouts } from 'virtual:generated-layouts'
import App from '~/App.vue'
import '~/assets/scss/main.scss'

const routes = setupLayouts(generatedRoutes)

const router = createRouter({
    history: createWebHashHistory(),
    routes
})

createApp(App).use(router).mount('#app')

Create a Default.vue file in the layouts folder with the following content:


<template>
    <div class="w-full min-h-full flex">
        <div class="flex flex-1 md:flex-0 mx-auto">
            <div class="flex-1 flex flex-col items-center">
                <div class="flex-1 flex flex-row w-full justify-center">
                <div class="flex-1 flex flex-col items-center shadow-lg x-w-2xl max-h-screen">
                    <RouterView />
                    <Footer />
                </div>
                </div>
            </div>
        </div>
    </div>
</template>

For example pages, I created 3 files in the pages folder: Index.vue, About.vue, Contacts.vue


Index.vue

<template>
  <div class="flex flex-col items-start w-full p-6 pb-8">
        <div class="flex flex-col items-center w-full p-6 space-y-8 mt-4">
            <div class="flex flex-col items-center space-y-3">
                <span class="text-base">Home</span>
            </div>
        </div>
    </div> 
</template>

<route lang="yaml">
    name: Index
    meta:
    layout: Default
</route>

About.vue

<template>
  <div class="flex flex-col items-start w-full p-6 pb-8">
        <div class="flex flex-col items-center w-full p-6 space-y-8 mt-4">
            <div class="flex flex-col items-center space-y-3">
                <span class="text-base">About</span>
            </div>
        </div>
    </div> 
</template>

<route lang="yaml">
    name: About
    meta:
    layout: Default
</route>

Contacts.vue

<template>
  <div class="flex flex-col items-start w-full p-6 pb-8">
        <div class="flex flex-col items-center w-full p-6 space-y-8 mt-4">
            <div class="flex flex-col items-center space-y-3">
                <span class="text-base">Contacts</span>
            </div>
        </div>
    </div> 
</template>

<route lang="yaml">
    name: Contacts
    meta:
    layout: Default
</route>

Manifest.json

At the root of our project, create a manifest.json file:

{
  "manifest_version": 2,
  "name": "Extension",
  "version": "0.1.0",
  "version_name": "0.1.0",
  "description": "Chrome Extension Example",
  "author": "Leonid Rezvitsky",
  "icons": {
    "128": "public/128.png"
  },
  "browser_action": {
    "default_popup": "dist/index.html",
    "default_title": "Extension"
  }
}

Build

To build the extension, run the command:

npm run build

Now go to the chrome://extensions page and enable developer mode.


Click on the button download the extension and select the folder where manifest.json is located in the crust.