Installation
Open the template, find your way around its folders and build your first page. There is nothing to install and no build step.
Open the template
- Unzip the download.
- Open
index.htmlin your browser. That's the CMS dashboard; every other page is linked from the sidebar.
You can open the pages straight from your disk. When you start building, a local web server is closer to how the pages will run in your project, with addresses like http://localhost:8000/index.html. Use whichever tool you already have, from inside the template folder:
# PHP
php -S localhost:8000
# Node.js
npx serve .
# Python
python -m http.server 8000
In VS Code, the Live Server extension does the same and reloads the page when you save a file.
Folder structure
Pages sit at the top level. Styles, scripts and images each have their own folder.
odinadmin/
├── index.html # CMS dashboard
├── index-analytics.html # Analytics dashboard
├── index-analytics-v2.html # Smartphone sales dashboard (world map)
├── index-ecommerce.html # Ecommerce dashboard
├── index-crm.html # CRM dashboard
├── index-finance.html # Finance dashboard (filters, forecast, insights)
├── index-support.html # Support dashboard (tickets, SLA, heatmap, live queue)
├── … # the other 34 pages
├── css/
│ ├── style.css # the only stylesheet a page links — imports all parts below
│ ├── base/ # variables, colour palette, base element styles
│ ├── layout/ # app shell, sidebar, top bar, footer
│ ├── components/ # buttons, forms, cards, tables, alerts, …
│ ├── pages/ # styles used by one page only
│ └── vendor/ # themes for third-party plugins
├── js/
│ ├── app.js # core — loaded on every page
│ └── … # one script per feature, loaded where needed
├── images/ # logos and favicons
├── json/ # demo data the pages load (finance.json, support.json, tickets.json) — edit it, or point the page at your own URL
├── docs/ # this documentation
└── changelogs.md # what changed in each release
CSS files
Every page links one file, css/style.css. It only imports the part files, in this order: variables → base → layout → components → pages → vendor. Edit the part files, never style.css itself.
| Folder | Files | What's inside |
|---|---|---|
base/ | variables, palette, base | CSS variables (colours, sizes, radius, shadows), the status colour classes, and styles for plain elements. |
layout/ | app, sidebar, topbar, footer | The page shell every page shares. |
components/ | 19 files | Accordions, alerts, badges, breadcrumbs, buttons, cards, charts, drag & drop, dropdowns, forms, lists, modals, nav tree, pagination, progress, tables, tabs, tooltips, tree view. |
pages/ | auth, error, file-manager, finance-dashboard, messages, sales-dashboard, settings, support-dashboard, support-tickets, tasks | Styles that only one page (or one group of pages) uses. |
vendor/ | 8 files | Restyle Tom Select, flatpickr, Dropzone, SweetAlert2, Dragula, FullCalendar, ApexCharts and jsVectorMap to match the template. |
JavaScript files
js/app.js is the core and loads on every page. The other scripts each power one feature and load only on the pages that use it, after app.js.
| File | What it does | Needs |
|---|---|---|
app.js | Core: Odin.Component, sidebar, submenus, tooltips | Bootstrap bundle |
forms.js | Form widgets and validation | Tom Select, flatpickr, Dropzone — each optional |
auth.js | Sign-in, sign-up and password forms | forms.js |
alerts.js | Closable alerts and toasts (Toastr-style options) | — |
modals.js | Confirm and message dialogs | SweetAlert2 |
tables.js | Data tables: search, filters, sorting, paging, bulk select | — |
tree-table.js | Nested rows you can reorder by dragging | SortableJS |
navigation.js | Menu editor | SortableJS |
dragula.js | Drag & drop lists | Dragula |
tree-view.js | Tree view: checkboxes, search, drag & drop, menu | modals.js — optional |
chartjs.js | Charts from data attributes | Chart.js |
apexcharts.js | Charts from data attributes | ApexCharts |
data-source.js | Loads a page's JSON data (data-source URL with an inline fallback) | — |
support-dashboard.js | Support dashboard: KPIs, ticket flow, SLA, heatmap, channels, satisfaction, backlog, agents, live queue | data-source.js, apexcharts.js |
finance-dashboard.js | Finance dashboard: filters, KPIs, insights, what-if forecast, budget, invoices | data-source.js, apexcharts.js |
sales-dashboard.js | Smartphone sales dashboard: world map, country details, tables, charts | apexcharts.js, jsVectorMap |
file-manager.js | File Manager app | — |
messages.js | Messages app | alerts.js, modals.js — optional |
support-tickets.js | Support Tickets app | data-source.js; forms.js, alerts.js — optional |
calendar.js | Calendar app | forms.js, FullCalendar |
kanban.js | Task Management board | forms.js, SortableJS |
Your first page
The quickest way to a new page is to copy an existing one. Every page has the same shell — sidebar, top bar, content and footer — so you only change the title, the menu and the content.
1. Copy a page
Pick the page closest to what you need — a dashboard, a list, a form — and copy it under a new name, for example reports.html. For an empty start, breadcrumbs.html is short and simple. Then change the title:
<title>ODIN ADMIN · Reports</title>
2. Add it to the sidebar
Add a link to the sidebar and mark it as the current page with active and aria-current. Remove active from the link it had before.
<li class="nav-item">
<a href="reports.html" class="nav-link active" aria-current="page">
<i class="nav-ico fas fa-chart-pie"></i>
<span>Reports</span>
</a>
</li>
For a link inside a submenu, also open its parent: the parent link gets open and aria-expanded="true", and its .sb-subwrap gets open. The Layout page covers the sidebar in detail.
The sidebar is copied into every page, so a new menu item has to be added to each one. In a real project, move the sidebar into one shared file of your back end — see Integration.
3. Replace the content
Everything between <div class="content"> and the footer is yours. Start with a page header, then use Bootstrap's grid and the template's cards:
<body>
<div class="app">
<aside class="sidebar" id="sidebar">…</aside> <!-- as in every page -->
<div class="backdrop" id="backdrop"></div>
<div class="main-col">
<header class="topbar">…</header> <!-- as in every page -->
<div class="content">
<div class="page-header">
<div>
<h1 class="page-title">Reports</h1>
<p class="page-sub">One line about what this page is for.</p>
</div>
</div>
<div class="row g-4">
<div class="col-xl-6">
<div class="card">
<div class="card-header"><span>Monthly report</span></div>
<div class="card-body">…</div>
</div>
</div>
</div>
</div>
<footer class="footerbar">…</footer> <!-- as in every page -->
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="js/app.js"></script>
</body>
Adding a plugin to a page
When a page needs a plugin — a searchable select, a date picker, drag & drop — load the files in this order. form-elements.html is a working example.
- In
<head>: the plugin's own CSS (if it has one) beforecss/style.css, so the template's theme incss/vendor/wins. - Before
</body>: the Bootstrap bundle, thenjs/app.js, then the plugin, then the template script that uses it.
<!-- head -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tom-select@2.6.2/dist/css/tom-select.css">
<link rel="stylesheet" href="css/style.css">
<!-- end of body -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="js/app.js"></script>
<script src="https://cdn.jsdelivr.net/npm/tom-select@2.6.2/dist/js/tom-select.complete.min.js"></script>
<script src="js/forms.js"></script>
The Libraries table lists every plugin, its version and the pages that load it.
Working offline
Bootstrap, Font Awesome, the Inter font and the plugins load from public CDNs. To run without an internet connection — or to keep every file on your own server — download them and point the links at your copies:
- Download each library at the version in the page's link (for example
bootstrap@5.3.3) from its website or npm. - Put the files in a folder of your own, for example
vendor/bootstrap/. - Replace the CDN links in each page with the local paths.
<!-- CDN -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- local copy -->
<link href="vendor/bootstrap/bootstrap.min.css" rel="stylesheet">
Font Awesome's CSS expects its webfonts/ folder next to the css/ folder, so copy both. For Inter, you can host the font files yourself or drop the link — the pages then fall back to the system font.