Demo

Home shortcuts

How to add quick-access tiles on the ERP home screen with useHomeShortcutStore and ShortcutItem from @quan-erp/base-frontend.

Overview

Home shortcuts are icon tiles on the home screen for high-frequency actions (POS, scan, create invoice). Register them once during PluginModule.register() via the base-frontend shortcut store — not through AppRegistry.

  • Import useHomeShortcutStore and ShortcutItem from @quan-erp/base-frontend
  • Call useHomeShortcutStore().getState().add({…}) inside register()
  • Wrap the icon in <ShortcutItem>
  • Keep id unique across all plugins (prefer `${metadata.name}/…`)

1. Register a shortcut

Add shortcuts in frontend/src/index.tsx during register(). Provide pluginName, a unique id, displayName, a ShortcutItem-wrapped icon, and either toLink and/or onClick.

TSXfrontend/src/index.tsx
1import { ShoppingCart } from "lucide-react"; 2import { ShortcutItem, useHomeShortcutStore } from "@quan-erp/base-frontend"; 3import type { AppRegistryState, PluginModule } from "@quan-erp/shared-types"; 4import metadata from "../module.metadata.json" with { type: "json" }; 5 6const Plugin: PluginModule = { 7 register(_AppRegistry: AppRegistryState) { 8 useHomeShortcutStore().getState().add({ 9 pluginName: metadata.name, 10 id: `${metadata.name}/pos`, 11 displayName: "POS", 12 component: ( 13 <ShortcutItem> 14 <ShoppingCart size={25} /> 15 </ShortcutItem> 16 ), 17 toLink: `/${metadata.name}/pos`, 18 async onClick() { 19 // optional — dialogs, scans, side effects 20 }, 21 }); 22 }, 23}; 24 25export default Plugin;

2. Properties

Each add() entry configures one home tile.

  • pluginName — must equal module.metadata.json name
  • id — unique across plugins; recommended `${metadata.name}/feature`
  • displayName — label under the icon
  • component — ReactNode; must wrap the icon in <ShortcutItem>
  • toLink — optional route under the plugin namespace (e.g. `/${metadata.name}/pos`)
  • onClick — optional async handler for dialogs, scanners, or custom navigation

3. Navigation patterns

Use toLink for normal route jumps. Use onClick when the shortcut opens a dialog, starts a scan flow, or needs logic before navigate. You can combine both when useful.

  • Keep toLink under your plugin path namespace to avoid collisions
  • Align toLink with a real AppRegistry.route / menu path
  • Prefer IconPark / lucide icons sized ~25 for visual consistency
TSonClick-only (e.g. scan)
1useHomeShortcutStore().getState().add({ 2 pluginName: metadata.name, 3 id: `${metadata.name}/scan`, 4 displayName: "Scan", 5 component: ( 6 <ShortcutItem> 7 <ScanIcon size={25} /> 8 </ShortcutItem> 9 ), 10 async onClick() { 11 // open scanner / dialog — no toLink required 12 }, 13});

Critical rules

  • Register only in register() — not inside page components on mount
  • component must use ShortcutItem; bare icons break home layout styling
  • ids must be unique across installed plugins
  • pluginName must match metadata.name
  • Use for high-frequency actions — not every menu item

Checklist

  • Import ShortcutItem + useHomeShortcutStore from @quan-erp/base-frontend
  • add() in register() with pluginName, id, displayName, component
  • Wrap icon in <ShortcutItem>
  • Set toLink and/or onClick
  • Verify tile after quan-erp watch and install

Common failures

  • Tile missing — add() not called, wrong pluginName, or plugin not installed
  • Broken icon layout — missing ShortcutItem wrapper
  • Click does nothing — neither toLink nor onClick set, or route path mismatch
  • Duplicate / colliding tiles — non-unique id across plugins
  • Wrong destination — toLink not aligned with AppRegistry.route path