العربية • Deutsch • English • Español • Français • Italiano • 日本語 • 한국어 • Nederlands • Polski • Português (BR) • Русский • Türkçe • 简体中文
Escalated is an embeddable support ticket system with SLA tracking, escalation rules, agent workflows, and a customer portal. This repo contains all the shared frontend assets (Vue 3 + Inertia.js) used across every supported backend framework.
👉 Learn more, view demos, and compare Cloud vs Self-Hosted options athttps://escalated.dev
You don't install this package directly. Start with the backend package for your framework — it handles everything including pulling in these frontend assets.
- Ticket splitting — Split a reply into a new standalone ticket while preserving context
- Ticket snooze — Snooze tickets with presets (1h, 4h, tomorrow, next week) and automatic wake
- Saved views / custom queues — Save, name, and share filter presets as reusable ticket views
- Embeddable support widget — Drop-in
<script>widget with KB search, ticket form, and status check - Real-time updates — WebSocket support (Pusher/Reverb/Soketi) with automatic polling fallback
- Knowledge base toggle — Enable or disable the public knowledge base from admin settings
- CI: ESLint + Prettier — Automated code style enforcement on every pull request
Pick your framework:
| Framework | Repo | Install |
|---|---|---|
| Laravel | escalated-dev/escalated-laravel | composer require escalated-dev/escalated-laravel |
| Rails | escalated-dev/escalated-rails | gem "escalated" |
| Django | escalated-dev/escalated-django | pip install escalated-django |
| AdonisJS | escalated-dev/escalated-adonis | npm install @escalated-dev/escalated-adonis |
| WordPress | escalated-dev/escalated-wordpress | Download escalated.zip |
| Filament | escalated-dev/escalated-filament | composer require escalated-dev/escalated-filament |
| React Native | escalated-dev/escalated-react-native | npm install @escalated-dev/escalated-react-native |
| Flutter | escalated-dev/escalated-flutter | See pubspec.yaml setup |
Each backend repo has full setup instructions — install command, migrations, config, and frontend integration.
Escalated components use Tailwind CSS utility classes (~hundreds of them across 140+ Vue files). Some Tailwind-compatible class processor must be available in the host app for the UI to render correctly — without one, every component renders as unstyled DOM with class names that don't resolve to any CSS.
If your host app already uses Tailwind via Vite / PostCSS / Tailwind CLI, just add this package to your content config so its classes aren't purged:
// tailwind.config.jsexportdefault{content: [// ... your existing paths'./node_modules/@escalated-dev/escalated/src/**/*.vue',],}Tailwind 4+ users:
contentglobs are auto-detected from imported modules — you usually don't need to add anything. Skip this step if you're on v4.
If you don't want a Tailwind toolchain in your build pipeline, you have a few options. Each has trade-offs — pick the one closest to your project's constraints:
| Option | When to use | How |
|---|---|---|
| Tailwind Play CDN | Prototyping, internal tools, demos. Not recommended for production (no purging, ~3 MB script tag). | Add <script src="https://cdn.tailwindcss.com"></script> to the page that renders Escalated. The CDN script JIT-compiles classes at runtime. |
| Tailwind standalone CLI | You want a static stylesheet without npm/Vite. | Download the standalone CLI binary and run tailwindcss -i input.css -o public/escalated.css --content './node_modules/@escalated-dev/escalated/src/**/*.vue' --minify. Link the output stylesheet from your page. |
| UnoCSS / Twind in attributify mode | Already using one of these atomic-CSS engines. | Configure with the Tailwind preset (@unocss/preset-wind or @twind/preset-tailwind) and add the Escalated package path to the engine's scan config. Class semantics match. |
| Forking with hand-rolled CSS | You categorically cannot ship any Tailwind-compatible tooling and are willing to maintain a fork. | Replace utility classes with scoped CSS per component. Substantial effort; not officially supported. |
If none of these fit, please open a discussion so we can understand the constraint and consider a pre-compiled CSS distribution.
Whatever path you choose, also make sure the theme tokens (CSS custom properties) are applied — those control colour, spacing, and radius and are independent of Tailwind.
Escalated renders inside a standalone layout by default. To integrate it into your app's design system, use the EscalatedPlugin:
import{createApp}from'vue'import{EscalatedPlugin}from'@escalated-dev/escalated'importAppLayoutfrom'@/Layouts/AppLayout.vue'constapp=createApp(...)app.use(EscalatedPlugin,{layout: AppLayout,theme: {primary: '#3b82f6',radius: '0.75rem',}})Pass your app's layout component and all Escalated pages render inside it automatically. The layout component must accept a #header slot and a default slot:
<!-- Your layout must support these slots -->
<template>
<div>
<nav>...</nav>
<header><slotname="header" /></header>
<main><slot /></main>
</div>
</template>When no layout is provided, Escalated uses its own built-in navigation bar.
The theme option sets CSS custom properties you can reference in your own styles:
| Property | Default | Description |
|---|---|---|
--esc-primary | #4f46e5 | Primary action color |
--esc-primary-hover | auto-darkened | Primary hover color |
--esc-radius | 0.5rem | Border radius for inputs and buttons |
--esc-radius-lg | auto-scaled | Border radius for cards and panels |
--esc-font-family | inherit | Font family override |
Laravel (Inertia + Vue 3):
import{EscalatedPlugin}from'@escalated-dev/escalated'importAuthenticatedLayoutfrom'@/Layouts/AuthenticatedLayout.vue'app.use(EscalatedPlugin,{layout: AuthenticatedLayout})Rails (Inertia + Vue 3):
import{EscalatedPlugin}from'@escalated-dev/escalated'importAppLayoutfrom'@/layouts/AppLayout.vue'app.use(EscalatedPlugin,{layout: AppLayout})Django (Inertia + Vue 3):
import{EscalatedPlugin}from'@escalated-dev/escalated'importBaseLayoutfrom'@/layouts/BaseLayout.vue'app.use(EscalatedPlugin,{layout: BaseLayout})AdonisJS (Inertia + Vue 3):
import{EscalatedPlugin}from'@escalated-dev/escalated'importAppLayoutfrom'@/layouts/AppLayout.vue'app.use(EscalatedPlugin,{layout: AppLayout})All the Vue 3 + Inertia.js components that power the Escalated UI. These are identical across Laravel, Rails, Django, and AdonisJS — the backend framework renders them via Inertia.
Screenshots are auto-generated from Storybook via the component-screenshots workflow.
Customer Portal — Self-service ticket management
pages/Customer/Index.vue— Ticket list with status filters and searchpages/Customer/Create.vue— New ticket form with file attachmentspages/Customer/Show.vue— Ticket detail with reply thread
Agent Dashboard — Ticket queue and workflows
pages/Agent/Dashboard.vue— Stats overview and recent ticketspages/Agent/TicketIndex.vue— Filterable ticket queuepages/Agent/TicketShow.vue— Full ticket view with sidebar, internal notes, canned responses
Admin Panel — System configuration
pages/Admin/Reports.vue— Analytics dashboardpages/Admin/Departments/— Department CRUDpages/Admin/SlaPolicies/— SLA policy managementpages/Admin/EscalationRules/— Escalation rule builderpages/Admin/Tags/— Tag managementpages/Admin/CannedResponses/— Canned response templates
Reusable building blocks used across the pages above.
| Component | Description |
|---|---|
StatusBadge | Colored badge for ticket status |
PriorityBadge | Colored badge for ticket priority |
TicketList | Paginated ticket table |
ReplyThread | Chronological reply display |
ReplyComposer | Reply/note editor with file upload and canned response insertion |
ActivityTimeline | Audit log of ticket events |
SlaTimer | SLA countdown with breach/warning states |
TicketFilters | Status, priority, agent, department filter bar |
TicketSidebar | Ticket detail sidebar (status, SLA, tags, activity) |
AssigneeSelect | Agent assignment dropdown |
TagSelect | Multi-select tag picker |
FileDropzone | Drag-and-drop file upload |
AttachmentList | File attachment display with download links |
StatsCard | Metric card with label, value, and trend |
EscalatedLayout | Top-level layout with navigation (supports host layout injection) |
BulkActionBar | Toolbar for batch operations on selected tickets |
QuickFilters | One-click filter chips (My Tickets, Unassigned, Urgent, SLA Breaching) |
MacroDropdown | Dropdown to apply multi-step macros to a ticket |
FollowButton | Toggle button to follow/unfollow a ticket |
SatisfactionRating | 1-5 star CSAT rating input with optional comment |
KeyboardShortcutHelp | Modal overlay showing all available keyboard shortcuts |
PinnedNotes | Display pinned internal notes at the top of the thread |
PresenceIndicator | Real-time indicator showing who is viewing a ticket |
| Composable | Description |
|---|---|
useKeyboardShortcuts | Registers and manages keyboard shortcuts for ticket actions |
| Export | Description |
|---|---|
EscalatedPlugin | Vue plugin for layout injection and CSS theming |
Escalated supports framework-agnostic plugins built with the Plugin SDK. Plugins are written once in TypeScript and work across all Escalated backends.
The frontend uses defineEscalatedPlugin() to register Vue components — custom admin pages, ticket sidebar widgets, or dashboard panels — that are mounted automatically when the plugin is active.
import{defineEscalatedPlugin}from'@escalated-dev/escalated'importMySettingsPagefrom'./MySettingsPage.vue'exportdefaultdefineEscalatedPlugin({name: 'my-plugin',pages: {'admin/my-plugin/settings': MySettingsPage,},})The backend uses definePlugin() from the Plugin SDK to handle TypeScript business logic — subscribing to ticket lifecycle hooks, exposing API endpoints, and persisting data. The frontend and backend entries work together as a single npm package.
// backend entry (index.ts)import{definePlugin}from'@escalated-dev/plugin-sdk'exportdefaultdefinePlugin({name: 'my-plugin',version: '1.0.0',actions: {'ticket.created': async(event,ctx)=>{ctx.log.info('New ticket!',event)},},})A published plugin package typically exports both:
my-plugin/
index.ts ← backend: definePlugin() for TypeScript logic
frontend.ts ← frontend: defineEscalatedPlugin() for Vue components
The backend framework (Laravel, Rails, Django, AdonisJS) loads index.ts via the Plugin Runtime. The Vue app imports frontend.ts and registers it with app.use().
npm install @escalated-dev/plugin-slack
npm install @escalated-dev/plugin-jira- Plugin SDK — TypeScript SDK for building plugins
- Plugin Runtime — Runtime host for plugins
- Plugin Development Guide — Full documentation
If you're building a new backend integration, this package is available on npm:
npm install @escalated-dev/escalated// Import the pluginimport{EscalatedPlugin}from'@escalated-dev/escalated'// Import individual componentsimport{StatusBadge,SlaTimer}from'@escalated-dev/escalated'// Or reference pages directly for Inertia resolutionimportCustomerIndexfrom'@escalated-dev/escalated/pages/Customer/Index.vue'Peer dependencies: vue ^3.3.0, @inertiajs/vue3 ^1.0.0 || ^2.0.0
This is the shared frontend for the Escalated support ticket system. Host framework packages and client SDKs available across the ecosystem:
- Escalated for Laravel — Laravel Composer package
- Escalated for Rails — Ruby on Rails engine
- Escalated for Django — Django reusable app
- Escalated for AdonisJS — AdonisJS v6 package
- Escalated for WordPress — WordPress plugin
- Escalated for Filament — Filament v3 admin panel plugin
- Escalated for React Native — React Native SDK
- Escalated for Flutter — Flutter SDK
- Shared Frontend — Vue 3 + Inertia.js UI components (you are here)
MIT






