Notika Admin Template

A green-themed Bootstrap 5 admin dashboard with 41 pages — dashboards, analytics, charts, forms, tables, email, and UI components. Powered by Vite 7.3 with ES6 modules and zero jQuery.

Template Info
Author Colorlib
License MIT
HTML Pages 41
Build System Vite 7.3.1
Technology Stack
CSS Framework Bootstrap 5.3.8
JavaScript ES6 Modules (no jQuery)
Icons Font Awesome 7.2
Charts Chart.js 4.5
Font Google Fonts Roboto
Animations AOS 2.3

What's Included

5
Dashboard layouts
4
Chart pages
10
UI component pages
6
Interface pages
3
Form pages
31
Page JS modules

Theme Colors

Notika uses a clean green accent on a white background:

#00c292
Primary green
#03a9f3
Info / secondary
#ff9800
Warning
#e91e63
Danger
#f8f9fa
Background

Getting Started

Notika uses Vite as its build system. You need Node.js installed to run the dev server and build for production.

Prerequisites

Node.js 18+ (LTS recommended)
npm 9+ (comes with Node)
Git Any modern version

Installation

  1. Clone the repository
    git clone https://github.com/nicdev/notika.git
    cd notika
  2. Install dependencies
    npm install

    This installs all npm packages listed in package.json (Bootstrap, Chart.js, Vite, etc.).

  3. Start the dev server
    npm run dev

    Opens the template at http://localhost:3100 with hot module replacement (HMR). Any changes to HTML, JS, or SCSS files reflect instantly.

  4. Build for production
    npm run build

    Outputs optimized files to dist/ with minified CSS/JS, code-split chunks, and sourcemaps.

Available Commands

Command Description
npm run dev Start Vite dev server with HMR on port 3100
npm run build Production build to dist/ directory
npm run preview Preview production build locally on port 4173
npm run lint Run ESLint to check code quality
npm run type-check Run TypeScript type checking
Tip: The dev server opens automatically in your browser. Use Ctrl+C to stop it. Changes to SCSS files trigger instant recompilation and injection without a full page reload.

Page Catalog

All 41 pages organized by category. Each page uses the shared horizontal navigation layout except auth and error pages.

Dashboards 5

Feature Chart.js charts, counter animations, widget cards, and data visualizations.

Charts 4

Powered by Chart.js 4.5 with bar, line, area, doughnut, and mixed chart types.

Interface 6

Code Editor uses CodeMirror 6, Image Cropper uses Cropper.js 2, Maps use Leaflet 1.9.

Auth & Error 2

These pages use a minimal layout without the header and navigation.

File Structure

The Vite root is notika/green-horizotal/ (not the project root). The vite.config.js lives at the project root.

  • notika/ — project root
    • package.json — dependencies and scripts
    • vite.config.js — Vite build config (multi-page, Handlebars, chunks)
    • notika/green-horizotal/ — Vite root
      • style.css — main theme (4,400+ lines, BS5 overrides)
      • *.html (41 pages)
      • src/js/ — ES6 modules
        • main.js — NotikaApp class, CSS imports, entry point (~1,185 lines)
        • modules/ — shared modules
          • charts.js — NotikaCharts (Chart.js wrapper, instance Map)
          • ui.js — NotikaUI (Bootstrap init, counters, toasts)

Key Files

vite.config.js Build configuration — multi-page input, Handlebars plugin, manual chunks, SCSS compilation, PostCSS
src/js/main.js NotikaApp class (~1,185 lines) — imports all CSS, registers Font Awesome icons, initializes navigation, mobile menu, AOS, charts
src/js/modules/charts.js NotikaCharts class — Chart.js wrapper storing instances in a Map for access, refresh, and destroy
src/js/modules/ui.js NotikaUI class — Bootstrap component init, counter animations via IntersectionObserver, toast notifications
style.css Main theme (4,400+ lines) — Bootstrap 5 overrides, component styles, layout rules
src/css/modern.scss Modern SCSS with CSS custom properties for spacing, card shadows, and design tokens

HTML Structure

All pages use a horizontal navigation layout with shared Handlebars partials for the header, navbar, footer, and breadcrumb.

Standardized Head

Every page uses this consistent <head> structure. CSS is imported through Vite (no <link> tags for libraries):

<html lang="en" data-page-module="pagename">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Page Title | Notika - Modern Vite Template</title>
    <meta name="description" content="...">

    <!-- Favicon -->
    <link rel="icon" type="image/svg+xml" href="/logo/notika-icon.svg">
    <link rel="alternate icon" href="/favicon.ico">

    <!-- Google Fonts (only external CSS link needed) -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">

    <!-- All other CSS imported via Vite in main.js -->
</head>
Important: Do not add <link> tags for Bootstrap, Font Awesome, AOS, or other libraries. They are all imported through main.js and bundled by Vite.

Standard Page Layout

Dashboard pages use this structure with Handlebars partials:

<body>
    <!-- Header with logo, search, notifications -->
    {{> header}}

    <!-- Horizontal dropdown navbar -->
    {{> navbar}}

    <!-- Breadcrumb -->
    {{> breadcrumb}}

    <!-- Page Content -->
    <div class="all-content-wrapper mg-b-15">
        <div class="container">
            <div class="row pt-3">
                <div class="col-lg-12">
                    <!-- Your content here -->
                </div>
            </div>
        </div>
    </div>

    <!-- Footer -->
    {{> footer}}

    <!-- Page module script -->
    <script type="module" src="/src/js/pages/pagename.js"></script>
</body>

Handlebars Partials

Four shared partials live in src/partials/ and are injected at build time:

Partial Description
header.hbs Top header bar with logo, search dropdown, message/notification/chat icons with badge counts
navbar.hbs Horizontal dropdown navigation with 8 menu groups (Home, Email, Interface, Charts, Tables, Forms, Components, Pages)
breadcrumb.hbs Dynamic breadcrumb with section-based icons (computed from filename in vite.config.js)
footer.hbs Page footer with copyright and year (dynamic via Handlebars context)

Navigation Structure

The template uses two navigation modes based on viewport width:

Desktop (≥992px) Horizontal dropdown navbar (.notika-navbar.d-none.d-lg-block) with 8 menu groups and Bootstrap 5 dropdowns
Mobile (<992px) Offcanvas menu (#mobileNavOffcanvas) triggered by a hamburger button (.d-lg-none), forcefully hidden on desktop via CSS and JS

Card Pattern

Content cards follow this consistent structure:

<div class="recent-post-wrapper notika-shadow">
    <div class="recent-post-ctn">
        <div class="recent-post-title">
            <h2>Card Title</h2>
        </div>
        <div class="recent-post-items">
            <!-- Card body content -->
        </div>
    </div>
</div>

Architecture

Notika uses a class-based ES6 module architecture with inheritance. A base NotikaApp class handles shared initialization, and page-specific modules extend it.

Class Hierarchy

NotikaApp (main.js)
 ├── NotikaCharts (modules/charts.js)    — Chart.js wrapper
 ├── NotikaUI (modules/ui.js)            — Bootstrap components, counters, toasts
 │
 └── Page Modules (pages/*.js)           — 31 modules extending NotikaApp
      ├── AnalyticsPage
      ├── BarChartsPage
      ├── DataTablePage
      ├── TabsPage
      └── ... (28 more)

How Pages Work

There are two types of pages:

Pages with custom logic

These set data-page-module on <html> and load a page-specific script. This prevents NotikaApp from auto-initializing:

<html lang="en" data-page-module="analytics">
...
<script type="module" src="/src/js/pages/analytics.js"></script>

Pages without custom logic

These omit data-page-module and load main.js directly. NotikaApp auto-initializes at the bottom of main.js:

<html lang="en">
...
<script type="module" src="/src/js/main.js"></script>

Page Module Pattern

Every page module follows this structure:

import { NotikaApp } from '../main.js'

class MyPage extends NotikaApp {
  async init() {
    await super.init()  // Initialize shared features
    // Page-specific setup here
    this.initCustomChart()
    this.initSpecialWidget()
  }

  initCustomChart() {
    const el = document.getElementById('my-chart')
    if (!el) return  // Guard clause
    // Chart initialization...
  }
}

// Instantiate when DOM is ready
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', () => {
    window.myPage = new MyPage()
    window.myPage.init()
  })
} else {
  window.myPage = new MyPage()
  window.myPage.init()
}

export { MyPage }

Shared Modules

Module Class Responsibility
modules/charts.js NotikaCharts Wraps Chart.js — stores instances in a Map, manages color palette, handles initialization of sales/items/sparkline/knob charts, provides access/refresh/destroy methods
modules/ui.js NotikaUI Bootstrap component initialization (tooltips, popovers), counter animations using IntersectionObserver + requestAnimationFrame, toast notification system

CSS Loading Strategy

All CSS is imported through main.js via Vite. This means:

  • No <link> tags needed for any library CSS
  • Vite bundles, minifies, and code-splits CSS automatically
  • Only Google Fonts and mobile menu CSS use traditional <link> tags
// In main.js — CSS imports (order matters)
import 'bootstrap/dist/css/bootstrap.css'
import 'aos/dist/aos.css'
import 'leaflet/dist/leaflet.css'
import 'swiper/css'
import '../../css/header-modern-clean.css'
import '../../css/navbar-stable.css'
import '../../css/responsive.css'
import '../../css/widgets-consistent.css'
import '../../style.css'
import '../css/modern.scss'
import '../css/dashboard-widgets.css'

JavaScript

All JavaScript is vanilla ES6 modules — no jQuery. The main entry point registers Font Awesome icons, imports CSS, and initializes the NotikaApp class.

Design Principles

  • One function per featureinitMobileMenu(), initScrollbarCleanup(), etc.
  • Guard clauses — every function starts with if (!el) return to skip gracefully on pages where elements don't exist
  • No global state — library instances are scoped within their init function or class
  • Modern APIsIntersectionObserver, requestAnimationFrame, classList, querySelectorAll
  • AOS initialized outside DOMContentLoaded — scripts are at the body bottom, so AOS must run immediately

Font Awesome Tree-Shaking

Icons are explicitly imported and registered. Only imported icons are bundled:

// In main.js
import { library, dom } from '@fortawesome/fontawesome-svg-core'
import { faHouse, faEnvelope, faBell, faChartColumn, ... }
  from '@fortawesome/free-solid-svg-icons'
import { faGithub, faTwitter, ... }
  from '@fortawesome/free-brands-svg-icons'

library.add(faHouse, faEnvelope, faBell, faChartColumn, ...)
dom.watch()  // Converts <i> tags to SVGs

To use a new icon:

  1. Import it: import { faNewIcon } from '@fortawesome/free-solid-svg-icons'
  2. Register it: add to library.add(...)
  3. Use in HTML: <i class="fa-solid fa-new-icon"></i>

NotikaApp Class Methods

  • async init() Main initialization — calls all sub-initializers in order
  • initCharts() Creates NotikaCharts instance, initializes Chart.js charts
  • initUI() Creates NotikaUI instance for Bootstrap components and counters
  • initAOS() Scroll-reveal animations via AOS (initialized outside DOMContentLoaded)
  • initMobileMenu() Offcanvas mobile navigation with prevention on desktop
  • preventMobileMenuOnDesktop() Blocks offcanvas show event on ≥992px viewports
  • removeAllScrollbarRules() Strips webkit scrollbar CSS rules to restore native scrollbars

Auto-Initialization

At the bottom of main.js, the app checks for data-page-module. If absent, it auto-initializes:

// At bottom of main.js (line ~1181)
if (!document.documentElement.dataset.pageModule) {
  const app = new NotikaApp()
  app.init()
}

Page modules that set data-page-module handle their own initialization by extending NotikaApp and calling super.init().

Chart.js Registration

Chart.js components are registered globally in main.js so all page modules can use them:

import { Chart, registerables } from 'chart.js'
Chart.register(...registerables)
window.bootstrap = bootstrap  // Also exposed globally

CSS & Styling

CSS is loaded through Vite imports in main.js. The template uses a mix of compiled CSS files and modern SCSS with CSS custom properties.

CSS Architecture

File Purpose
style.css Main theme (4,400+ lines) — all Bootstrap 5 overrides, component styles, layout, cards, forms
src/css/modern.scss Modern SCSS with CSS custom properties (--notika-spacing-*), card shadows, design tokens
css/header-modern-clean.css Header bar styling — .notika-header, dropdown menus, icon badges
css/navbar-stable.css Horizontal dropdown navigation — .notika-navbar, active states, transitions
css/mobile-menu.css Offcanvas mobile menu — responsive toggle, forced hiding on desktop
css/responsive.css Legacy responsive breakpoints (being gradually cleaned up)
css/widgets-consistent.css Widget card spacing and grid layout consistency

CSS Custom Properties

Spacing and design tokens use CSS custom properties defined in modern.scss:

:root {
    --notika-spacing-xs: 8px;
    --notika-spacing-sm: 16px;
    --notika-spacing-md: 24px;
    --notika-spacing-lg: 32px;
}

Card Shadows

/* Default card shadow */
.notika-shadow {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* Hover state */
.notika-shadow:hover {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}

Z-Index Layers

Header z-index: 1090 (header-modern-clean.css)
Navbar z-index: 1085 (navbar-stable.css)
Mobile Offcanvas z-index: 1045 (Bootstrap default)

SCSS Compilation

SCSS uses the modern compiler API via Vite, with PostCSS for autoprefixer and cssnano:

// In vite.config.js
css: {
  preprocessorOptions: {
    scss: { api: 'modern-compiler' }
  },
  postcss: {
    plugins: [autoprefixer(), cssnano({ preset: 'default' })]
  }
}

Build System

Notika uses Vite 7.3.1 as its build tool. The config lives at the project root but sets root to ./notika/green-horizotal.

Multi-Page Setup

All 41 HTML pages are listed as separate entry points in rollupOptions.input. This ensures each page gets its own optimized bundle:

// vite.config.js
build: {
  outDir: '../../dist',
  rollupOptions: {
    input: {
      main: resolve(cwd, 'notika/green-horizotal/index.html'),
      analytics: resolve(cwd, 'notika/green-horizotal/analytics.html'),
      'index-2': resolve(cwd, 'notika/green-horizotal/index-2.html'),
      // ... 38 more pages
    }
  }
}

Code Splitting

Vite automatically code-splits, plus three manual chunks for better caching:

vendor Bootstrap CSS and JS — cached separately since it rarely changes
charts Chart.js — only loaded on pages with charts
ui Swiper + AOS — carousel and animation libraries

Handlebars Plugin

The vite-plugin-handlebars plugin provides template partials and dynamic context computed from the filename:

plugins: [
  handlebars({
    partialDirectory: resolve(cwd, 'notika/green-horizotal/src/partials'),
    context: (pagePath) => {
      const pageName = pagePath.split('/').pop()?.replace('.html', '')
      return {
        pageTitle: pageName.charAt(0).toUpperCase() + pageName.slice(1),
        year: new Date().getFullYear(),
        isHome: ['index', 'analytics', 'widgets'].some(p => pageName.includes(p)),
        isCharts: ['bar-charts', 'line-charts', ...].some(p => pageName.includes(p)),
        // ... more nav active flags
        breadcrumbIcon: pageName.includes('chart') ? 'fa-solid fa-chart-column' : '...'
      }
    }
  })
]

Dev Server

Port 3100
HMR Enabled
Auto Open Yes
CORS Enabled

Production Build

Output dist/ (project root)
Target ES2022
Minifier esbuild
Sourcemaps Yes

Path Aliases

resolve: {
  alias: {
    '@': resolve(cwd, './src'),
    '@css': resolve(cwd, './notika/green-horizotal/css'),
    '@js': resolve(cwd, './notika/green-horizotal/js'),
    '@img': resolve(cwd, './notika/green-horizotal/img')
  }
}

Libraries & Dependencies

All libraries are bundled via Vite from npm packages. No CDN links, no local vendor files. This section lists every dependency and its purpose.

Core Stack

Library Version Purpose
Vite 7.3.1 Build system with HMR, code splitting, SCSS, multi-page support
Bootstrap 5.3.8 CSS framework + JS components (dropdowns, modals, tooltips, offcanvas)
Font Awesome 7.2.0 Tree-shaken SVG icons (solid + brand packages)

Charts & Maps

Library Version Used On
Chart.js 4.5.1 All dashboards and chart pages — bar, line, area, doughnut, sparkline
Leaflet 1.9.4 Google Map and Data Maps pages — interactive tile-based maps

UI & Animation

Library Version Purpose
Swiper 12.1.0 Touch-enabled carousel slider for dashboards
AOS 2.3.4 Scroll-reveal animations (fade, slide, zoom effects)
Animate.css 4.1.1 CSS animation library for the Animations page
Day.js 1.11.19 Lightweight date formatting and manipulation

Editors & Media

Library Version Purpose
CodeMirror 6.x In-browser code editor with HTML and JS language support, One Dark theme
Cropper.js 2.1.0 Image cropping and manipulation on the Image Cropper page

Dev Dependencies

Library Version Purpose
Sass 1.97.3 SCSS compilation with modern compiler API
PostCSS 8.5.6 CSS processing pipeline
Autoprefixer 10.4.24 Automatic vendor prefixes for cross-browser support
cssnano 7.1.2 CSS minification for production builds
TypeScript 5.9.3 Type checking (optional, via npm run type-check)
ESLint 10.0.0 Code linting (via npm run lint)
Prettier 3.8.1 Code formatting
vite-plugin-handlebars 2.0.0 Handlebars template partials and dynamic context

Customization

How to modify the template's appearance and behavior to match your project requirements.

Changing Theme Colors

The primary green color (#00c292) is used throughout the template. To change it, search and replace in these files:

/* style.css — Primary accent color */
/* Search for #00c292 and replace globally */

/* src/js/modules/charts.js — Chart colors */
this.colors = {
  primary: '#00c292',    /* Change this */
  secondary: '#03a9f3',
  success: '#00c292',
  warning: '#ff9800',
  danger: '#e91e63',
  info: '#03a9f3'
}

Adding a New Page

  1. Create the HTML file

    Copy an existing page (e.g. tabs.html) to notika/green-horizotal/newpage.html. Update the <title> and content.

  2. Register in Vite config

    Add the page to rollupOptions.input in vite.config.js:

    newpage: resolve(process.cwd(), 'notika/green-horizotal/newpage.html'),
  3. Create a page module (optional)

    If the page needs custom JavaScript, create src/js/pages/newpage.js:

    import { NotikaApp } from '../main.js'
    
    class NewPage extends NotikaApp {
      async init() {
        await super.init()
        // Custom logic here
      }
    }
    
    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', () => {
        window.newPage = new NewPage()
        window.newPage.init()
      })
    } else {
      window.newPage = new NewPage()
      window.newPage.init()
    }
    
    export { NewPage }
  4. Set the data attribute and script

    In your HTML, set data-page-module and load the page script:

    <html lang="en" data-page-module="newpage">
    ...
    <script type="module" src="/src/js/pages/newpage.js"></script>

Adding Font Awesome Icons

Icons are tree-shaken, so only imported icons are bundled. To add a new icon:

// 1. Import in main.js
import { faNewIcon } from '@fortawesome/free-solid-svg-icons'

// 2. Add to library.add() call
library.add(faHouse, faEnvelope, faBell, faNewIcon, ...)

// 3. Use in HTML
<i class="fa-solid fa-new-icon"></i>
Tip: Both @fortawesome/free-solid-svg-icons and @fortawesome/free-brands-svg-icons packages are available. Browse all icons at fontawesome.com.

Adding Charts

Chart.js is globally registered. Add a canvas element and initialize:

<!-- 1. Add a canvas -->
<canvas id="myChart"></canvas>

<!-- 2. Initialize in your page module -->
// In your page module's init()
initMyChart() {
  const canvas = document.getElementById('myChart')
  if (!canvas) return

  new Chart(canvas, {
    type: 'bar',
    data: {
      labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
      datasets: [{
        label: 'Sales',
        data: [30, 40, 35, 50, 49],
        backgroundColor: '#00c292'
      }]
    },
    options: {
      responsive: true,
      plugins: { legend: { display: false } }
    }
  })
}

Modifying the Navigation

The navigation is defined in src/partials/navbar.hbs. To add a new menu item:

<!-- In navbar.hbs -->
<li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown">
        <i class="fa-solid fa-star"></i>
        <span>New Section</span>
    </a>
    <ul class="dropdown-menu">
        <li><a class="dropdown-item" href="newpage.html">New Page</a></li>
    </ul>
</li>

Don't forget to add a corresponding active-state flag in vite.config.js's context function.

Responsive Breakpoints

992px and above Full horizontal navbar with dropdowns, desktop header layout
Below 992px Offcanvas mobile menu, hamburger toggle, simplified header
Below 768px Single-column layout, cards stack vertically, compact icon logo

Spacing Convention

The template follows a consistent spacing pattern:

  • mg-b-15 on the main content wrapper
  • pt-3 on the first .row inside content
  • mt-4 on subsequent rows
  • CSS custom properties for reusable spacing: --notika-spacing-xs (8px) through --notika-spacing-lg (32px)

Sources & Credits

Third-party libraries and resources used in this template.

Framework & Build

Charts & Maps

UI & Animation

Editors & Media

Build Tools

Support

Thank you for using Notika. If you have any questions or run into issues, we're here to help.

Browser Support

Chrome ≥ 90
Firefox ≥ 88
Safari ≥ 14
Edge ≥ 90
Opera ≥ 76
Note: Internet Explorer is not supported. The template uses ES2022 features and CSS custom properties that require modern browsers.

Need Help?

Our support team is happy to assist with questions about setup, customization, or troubleshooting.

Contact Colorlib