Color Admin

“Vue 3 + Vite JS Version” Documentation by “Sean Ngu” v6.0.0

CLI

Updated on: 25/August/2026
By: Sean Ngu

If you have any inquiries or require further assistance beyond what is covered in this help file, please do not hesitate to send us a message through Wrapbootstrap. We are more than happy to help.

Thank you very much!

Follow the following steps to install Vue 3 with Vite in your local development environment.
You may refer to their official documentation for how to setup the development environment.
Setup Guide

<!-- run the following command -->
cd /your-path-url/template_vue3
npm install
npm run dev

<!-- browse the url -->
http://localhost:8081/

Verify that you are running at least node 22.x.x or later and npm 11.x.x by running node -v and npm -v in a terminal/console window. Older versions produce errors, but newer versions are fine.


Copy over the required image from global assets folder

<!-- copy the following folder-->
/admin/template/assets/img
 
<!-- paste it into vue3 folder -->
/admin/template/template_vue3/public/assets/img

File structure overview for Vue JS Version

template_vue3/
├── .eslintrc.cjs
├── .gitignore
├── .vscode/
├── cypress/
├── cypress.json
├── env.d.ts
├── index.html
├── package.json
├── public/
├── README.md
├── src/
│   ├── App.vue
│   ├── assets/
│   ├── components/
│   ├── composables/
│   ├── main.ts
│   ├── router/
│   ├── scss/
│   ├── stores/
│   └── views/
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig-vite-config.json
└── tsconfig.vitest.json
    └── vite.config.ts

Below is the code from App.vue which include the header, sidebar, right sidebar, top menu, page content and footer. You may remove the component if you are not using it.

<template>
  <div class="app" v-bind:class="[{ 
    'app-header-menu-search-toggled': appOption.appHeaderSearchToggled,
    'app-header-fixed': appOption.appHeaderFixed,
    'app-sidebar-fixed': appOption.appSidebarFixed,
    'app-sidebar-grid': appOption.appSidebarGrid,
    'app-sidebar-toggled': appOption.appSidebarToggled,
    'app-sidebar-collapsed': appOption.appSidebarCollapsed,
    'app-sidebar-mobile-toggled': appOption.appSidebarMobileToggled,
    'app-sidebar-mobile-closed': appOption.appSidebarMobileClosed,
    'app-sidebar-end-toggled': appOption.appSidebarEndToggled,
    'app-sidebar-end-mobile-toggled': appOption.appSidebarEndMobileToggled,
    'app-content-full-height': appOption.appContentFullHeight,
    'app-content-full-width': appOption.appSidebarHide,
    'app-without-sidebar': appOption.appSidebarHide,
    'app-with-end-sidebar': appOption.appSidebarEnd,
    'app-with-wide-sidebar': appOption.appSidebarWide,
    'app-with-hover-sidebar': appOption.appSidebarHover,
    'app-with-top-menu': appOption.appTopMenu,
    'app-with-two-sidebar': appOption.appSidebarTwo,
    'pt-0': appOption.appHeaderHide,
    'app-boxed-layout': appOption.appBoxedLayout,
    'app-footer-fixed': appOption.appFooterFixed,
    'app-sidebar-minified': appOption.appSidebarMinified,
    'app-gradient-enabled': appOption.appGradientEnabled
  }, appOption.appClass]"">
    <vue3-progress-bar />
    <app-header v-if="!appOption.appHeaderHide" />
    <app-sidebar v-if="!appOption.appSidebarHide" />
    <app-sidebar-right v-if="appOption.appSidebarTwo" />
    <app-top-menu v-if="appOption.appTopMenu" />
    <div class="app-content" v-bind:class="appOption.appContentClass">
      <router-view></router-view>
    </div>
    <app-footer v-if="appOption.appFooter" />
    <app-theme-panel />
  </div>
</template>

List of components inside the components folder

/src/components/
├── app/
│   ├── AnimateNumber.vue
│   ├── Footer.vue
│   ├── Header.vue
│   ├── HeaderMegaMenu.vue
│   ├── NavScrollTo.vue
│   ├── Sidebar.vue
│   ├── SidebarNav.vue
│   ├── SidebarRight.vue
│   ├── ThemePanel.vue
│   ├── TopMenu.vue
│   └── TopMenuNav.vue
├── bootstrap/
│   ├── Panel.vue
│   ├── PanelBody.vue
│   ├── PanelFooter.vue
│   ├── PanelGroup.vue
│   ├── PanelHeader.vue
│   ├── PanelTitle.vue
│   └── PanelToolbar.vue
└── plugins/
    ├── Apexcharts.vue
    ├── Chartjs.vue
    ├── Datepicker.vue
    ├── Highlightjs.vue
    ├── QuillEditor.vue
    ├── TagsInput.vue
    ├── Typeahead.vue
    ├── VueSelect.vue
    └── VueTable.vue

This template used mitt as event bus to emit events between component. Emitter files can be found via /composables/useEmitter.ts

import useEmitter from '@/composables/useEmitter';

const emitter = useEmitter();

// emit event
emitter.emit('my-event', true);

// event listener
this.emitter.on('my-event', (evt) => {
  // do something
});

This template used pinia to create the store and share the states variable between the components. Store files can be found via /src/stores/

/src/stores/
├─ app-option.ts            // global app option states
├─ app-sidebar-menu.ts      // global app sidebar menu list
└─ app-variable.ts          // global app variable (fetched from css / font variables)

You can use the global app option from /stores/app-option.ts

import { useAppOptionStore } from '@/stores/app-option';

const appOption = useAppOptionStore();

export default {
  mounted() {
    // available app option
    appOption.appThemeClass: '',
    appOption.appDarkMode: '',
    
    appClass: '',
    
    appOption.appHeaderHide: false,
    appOption.appHeaderFixed: true,
    appOption.appHeaderInverse: false,
    appOption.appHeaderSearchToggled: false,
    appOption.appHeaderLanguageBar: false,
    appOption.appHeaderMegaMenu: false,
    
    appOption.appSidebarTwo: false,
    appOption.appSidebarHide: false,
    appOption.appSidebarEnd: false,
    appOption.appSidebarWide: false,
    appOption.appSidebarLight: false,
    appOption.appSidebarFixed: true,
    appOption.appSidebarCollapsed: false,
    appOption.appSidebarMobileToggled: false,
    appOption.appSidebarMobileClosed: false,
    appOption.appSidebarMinified: false,
    appOption.appSidebarHover: false,
    appOption.appSidebarSearch: false,
    appOption.appSidebarEndToggled: false,
    appOption.appSidebarEndMobileToggled: false,
    appOption.appSidebarTransparent: false,
    
    appOption.appTopMenu: false,
    
    appOption.appContentFullHeight: false,
    appOption.appContentClass: '',
    
    appOption.appFooter: false,
    appOption.appFooterFixed: false,
    
    appOption.appThemePanelToggled: false
  },
  beforeUnmount() {
    // set to default before leave the page
    appOption.appTopMenu = false;
  }
}

You can use the global app variables (css color / font family) from /stores/app-variable.ts

import { useAppVariableStore } from '@/stores/app-variable';

const appVariable = useAppVariableStore();

export default {
  data() {
    return {
      variableName: appVariable.color.theme
      
      // font variable
      appVariable.font.family;
      appVariable.font.size;
      appVariable.font.weight;
      
      // color variable
      appVariable.color.componentColor;
      appVariable.color.componentBg;
      appVariable.color.theme;
      appVariable.color.blue;
      appVariable.color.green;
      appVariable.color.orange
      appVariable.color.red;
      appVariable.color.cyan;
      appVariable.color.purple;
      appVariable.color.yellow;
      appVariable.color.indigo;
      appVariable.color.pink;
      appVariable.color.black;
      appVariable.color.white;
      appVariable.color.gray;
      appVariable.color.dark;
      appVariable.color.gray100;
      appVariable.color.gray200;
      appVariable.color.gray300;
      appVariable.color.gray400;
      appVariable.color.gray500;
      appVariable.color.gray600;
      appVariable.color.gray700;
      appVariable.color.gray800;
      appVariable.color.gray900;
      
      // color variable (rgba)
      appVariable.color.componentColorRgb;
      appVariable.color.componentBgRgb;
      appVariable.color.themeRgb;
      appVariable.color.blueRgb;
      appVariable.color.greenRgb;
      appVariable.color.orange
      appVariable.color.redRgb;
      appVariable.color.cyanRgb;
      appVariable.color.purpleRgb;
      appVariable.color.yellowRgb;
      appVariable.color.indigoRgb;
      appVariable.color.pinkRgb;
      appVariable.color.blackRgb;
      appVariable.color.whiteRgb;
      appVariable.color.grayRgb;
      appVariable.color.darkRgb;
      appVariable.color.gray100Rgb;
      appVariable.color.gray200Rgb;
      appVariable.color.gray300Rgb;
      appVariable.color.gray400Rgb;
      appVariable.color.gray500Rgb;
      appVariable.color.gray600Rgb;
      appVariable.color.gray700Rgb;
      appVariable.color.gray800Rgb;
      appVariable.color.gray900Rgb;
    }
  }
}

Set the app sidebar menu list from from /stores/app-sidebar-menu.ts

// single level structure
{
  'url': '/',
  'icon': 'fa fa-sitemap',
  'text': 'Dashboard'
},

// multi level structure 
{
  'icon': 'fa fa-envelope',
  'text': 'Email',
  'children': [{
    'url': '/email/inbox',
    'action': 'Inbox',
    'text': 'Inbox'
  }, {
    'url': '/email/compose',
    'action': 'Compose',
    'text': 'Compose'
  }, {
    'url': '/email/detail',
    'action': 'Detail',
    'text': 'Detail'
  }]
}

Enable the dark mode from template_vue3/stores/app-variable.ts

...
appDarkMode: true
...

Add the dir="rtl" attribute to <html> for index.html in order to enable Right-To-Left (RTL) layout direction.

<html dir="rtl">

This will flip the layout direction of the entire page to support RTL languages like Arabic, Hebrew, or Persian.

Replace the existing @import 'default/styles'; line in template_vue3/src/scss/vue.scss with the selected theme import below, then restart the Vite development server.

Apple Design

  1. Change the variable from template_vue3/src/scss/vue.scss.
    @import 'apple/styles';
    
  2. No additional icon script is required for the current Iconify-based components.
    <!-- No additional icon script is required. -->
    
  3. The current component uses Iconify icons, so no additional icon-library change is required.
    <div class="menu-icon">
      <iconify-icon icon="solar:pulse-bold-duotone"></iconify-icon>
    </div>
    

Facebook Design

  1. Change the variable from template_vue3/src/scss/vue.scss.
    @import 'facebook/styles';
    
  2. Enable the app header inverse from template_vue3/stores/app-option.ts.
    ...
    appHeaderInverse: true
    ...
    

Transparent Design

  1. Change the variable from template_vue3/src/scss/vue.scss.
    @import 'transparent/styles';
    
  2. Add the .app-cover next to the <body> tag in template_vue3/public/index.html.
    <body>
      <!-- BEGIN page-cover -->
      <div class="app-cover"></div>
      <!-- END page-cover -->
      
      ...
    </body>
    

Google Design

  1. Change the variable from template_vue3/src/scss/vue.scss.
    @import 'google/styles';
    
  2. The current component uses Iconify icons, so no additional icon-library change is required.
    <div class="menu-icon">
      <iconify-icon icon="solar:home-2-bold-duotone"></iconify-icon>
    </div>
    
  3. Enable the app sidebar light & wide option from template_vue3/stores/app-option.ts.
    ...
    appSidebarWide: true,
    appSidebarLight: true,
    ...
    
  4. Add the navbar desktop toggler to the .app-header in template_vue3/src/components/app/Header.vue.
    <!-- BEGIN #appHeader -->
    <div id="appHeader" class="app-header">
      <!-- BEGIN brand -->
      <div class="brand">
        <button type="button" class="menu-toggler">
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <button type="button" class="menu-toggler">
          ...
        </button>
        <a class="brand-logo">
          Color Admin
        </a>
      </div>
      <!-- END brand -->
      ...
    </div>
    

Material Design

  1. Change the variable from template_vue3/src/scss/vue.scss.
    @import 'material/styles';
    
  2. The current component uses Iconify icons, so no additional icon-library change is required.
    <div class="menu-icon">
      <iconify-icon icon="solar:home-2-bold-duotone"></iconify-icon>
    </div>
    
  3. Enable the app sidebar wide option from template_vue3/stores/app-option.ts.
    ...
    appSidebarWide: true,
    ...
    
  4. Add the navbar desktop toggler to the .app-header in template_vue3/src/components/app/Header.vue.
    <!-- BEGIN #appHeader -->
    <div id="appHeader" class="app-header">
      <!-- BEGIN brand -->
      <div class="brand">
        <button type="button" class="menu-toggler">
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <button type="button" class="menu-toggler">
          ...
        </button>
        <a class="brand-logo">
          Color Admin Material
        </a>
      </div>
      <!-- END brand -->
      ...
    </div>
    
  5. Customize the existing header search form in template_vue3/src/components/app/Header.vue. Do not add a second search form.
    <!-- BEGIN #appHeader -->
    <div id="appHeader" class="app-header">
      <!-- BEGIN header-nav -->
      <div class="menu">
        <div class="menu-item">
          <a href="#" class="menu-link icon">
            <i class="material-icons">search</i>
          </a>
          
          <!-- EXISTING SEARCH FORM -->
          <div class="menu-item menu-item-form">
            ...
          </div>
        </div>
        ...
      </div>
      <!-- END header-nav -->
      
      <div class="menu-item-form">
        <button class="search-btn" type="submit"><i class="material-icons">search</i></button>
        <input type="text" class="form-control" placeholder="Search Something..." />
        <a href="#" class="close">
          <i class="material-icons">close</i>
        </a>
      </div>
    </div>
    
  6. Change the .app-loader in template_vue3/public/index.html.
    <!-- BEGIN #loader -->
    <div id="loader" class="app-loader">
      <div class="material-loader">
        <svg class="circular" viewBox="25 25 50 50">
          <circle class="path" cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"></circle>
        </svg>
        <div class="message">Loading...</div>
      </div>
    </div>
    <!-- END #loader -->
    

The Vue 3 version is fully configured with SCSS. You may switch the Color Admin theme by changing the file /template_vue3/src/scss/vue.scss.

@import 'default/styles';
 
<!-- other themes -->
@import 'apple/styles';
@import 'facebook/styles';
@import 'google/styles';
@import 'material/styles';
@import 'transparent/styles';

Below is the list of package that has been installed in this project. You may use the following example to find the package from their official website. https://www.npmjs.com/package/bootstrap-vue

{
  "name": "color-admin",
  "version": "6.0.0",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc --noEmit && vite build",
    "preview": "vite preview --port 5050",
    "test:unit": "vitest --environment jsdom",
    "test:e2e": "start-server-and-test preview http://127.0.0.1:5050/ 'cypress open'",
    "test:e2e:ci": "start-server-and-test preview http://127.0.0.1:5050/ 'cypress run'",
    "typecheck": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
    "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
  },
  "type": "module",
  "dependencies": {
    "@caohenghu/vue-colorpicker": "^1.2.4",
    "@chenfengyuan/vue-countdown": "^2.1.3",
    "@fortawesome/fontawesome-free": "^7.3.1",
    "@fortawesome/fontawesome-svg-core": "^7.3.1",
    "@fortawesome/free-solid-svg-icons": "^7.3.1",
    "@fortawesome/vue-fontawesome": "^3.0.8",
    "@fullcalendar/bootstrap": "^6.1.21",
    "@fullcalendar/common": "^5.11.5",
    "@fullcalendar/core": "^6.1.21",
    "@fullcalendar/daygrid": "^6.1.21",
    "@fullcalendar/interaction": "^6.1.21",
    "@fullcalendar/list": "^6.1.21",
    "@fullcalendar/timegrid": "^6.1.21",
    "@fullcalendar/vue3": "^6.1.21",
    "@highlightjs/vue-plugin": "github:highlightjs/vue-plugin",
    "@marcoschulte/vue3-progress": "^0.0.9",
    "@sipec/vue3-tags-input": "^3.0.4",
    "@vuepic/vue-datepicker": "^11.0.2",
    "@vueup/vue-quill": "^1.2.0",
    "apexcharts": "^6.7.0",
    "axios": "^1.10.0",
    "bootstrap": "^5.3.8",
    "bootstrap-icons": "^1.13.1",
    "bootstrap-social": "^5.1.1",
    "chart.js": "^4.5.0",
    "date-fns": "^4.1.0",
    "flag-icons": "^7.5.0",
    "highlight.js": "^11.11.1",
    "jsvectormap": "^1.7.0",
    "lity": "^2.4.1",
    "maska": "^3.2.0",
    "masonry-layout": "^4.2.2",
    "mitt": "^3.0.1",
    "moment": "^2.30.1",
    "photoswipe": "^5.4.4",
    "pinia": "^3.0.3",
    "simple-line-icons": "^2.5.5",
    "v-calendar": "^3.0.0-alpha.8",
    "vue": "^3.5.41",
    "vue-axios": "^3.5.2",
    "vue-router": "^4.5.1",
    "vue-select": "^4.0.0-beta.3",
    "vue3-apexcharts": "^1.8.0",
    "vue3-datepicker": "^0.4.0",
    "vue3-google-map": "^0.22.0",
    "vue3-perfect-scrollbar": "^2.0.0",
    "vue3-simple-typeahead": "^1.0.11",
    "vue3-table-lite": "^1.4.3"
  },
  "devDependencies": {
    "@iconify/vue": "^5.0.0",
    "@rushstack/eslint-patch": "^1.12.0",
    "@types/jsdom": "^21.1.7",
    "@types/node": "^24.0.10",
    "@vitejs/plugin-vue": "^6.0.0",
    "@vitejs/plugin-vue-jsx": "^5.0.1",
    "@vue/eslint-config-prettier": "^10.2.0",
    "@vue/eslint-config-typescript": "^14.6.0",
    "@vue/test-utils": "^2.4.6",
    "@vue/tsconfig": "^0.7.0",
    "cypress": "^14.5.1",
    "eslint": "^9.30.1",
    "eslint-plugin-cypress": "^5.1.0",
    "eslint-plugin-vue": "^10.3.0",
    "jsdom": "^26.1.0",
    "prettier": "^3.6.2",
    "sass": "1.77.7",
    "sass-loader": "^16.0.5",
    "start-server-and-test": "^2.0.12",
    "typescript": "~5.8.3",
    "vite": "^8.2.1",
    "vitest": "^3.2.4",
    "vue-tsc": "^3.0.1"
  }
}