Skip to content

Creating Dashboard Pages

Zeroknights edited this page Mar 28, 2026 · 6 revisions

This page explains how plugins can ship custom dashboard pages.


1. How loading works

When Athena starts and the dashboard is enabled, it checks every loaded plugin for:

  • /plugins/<plugin_name>/src/dashboard/addon.json

If present, Athena copies your plugin dashboard files into the main dashboard app and adds your addon to the sidebar automatically.

2. Required manifest

Create:

  • /plugins/<plugin_name>/src/dashboard/addon.json

Example:

{
  "name": "Template Addon",
  "slug": "template-addon",
  "icon": "TbPlug",
  "description": "Sample custom dashboard page bundled with the plugin template."
}

Required fields:

  • name: Sidebar/page title
  • slug: URL path key (must be unique)

Optional fields:

  • icon: Tabler icon key, defaults to TbPlug
  • description: Subtitle shown in addon layout header

slug should be lowercase kebab-case and should not change after release, otherwise old links/bookmarks break.

3. Folder structure

Use this structure inside your plugin:

src/dashboard/
  addon.json
  pages/
    page.jsx
  components/
    HelloCard.jsx
  api/
    ping/
      route.js

How each folder is used:

  • pages/: Copied to dashboard app route /addons/<slug>/...
  • components/: Copied to dashboard/components/addons/<slug>/...
  • api/: Copied to dashboard/app/api/addons/<slug>/...

4. Route and imports

For addon slug template-addon:

  • src/dashboard/pages/page.jsx becomes /addons/template-addon
  • import shared components from dashboard/components/addons/template-addon

Example import in your page.jsx:

import HelloCard from '../../../../components/addons/template-addon/HelloCard';

If you rename slug, update imports that include the old slug path.

The dashboard currently maps addon icons using a fixed icon map. If you use a custom icon key that is not available there, the UI falls back to TbPlug.

5. Fetching plugin data

The most common pattern is reading your plugin config through Web API dashboard routes:

const API_BASE = process.env.NEXT_PUBLIC_ATHENA_WEB_API_URL;
const API_KEY = process.env.NEXT_PUBLIC_ATHENA_WEB_API_KEY;

const response = await fetch(`${API_BASE}/api/dashboard/config/hello/data`, {
  headers: { authorization: API_KEY }
});

Save updates with:

await fetch(`${API_BASE}/api/dashboard/config/hello/save`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', authorization: API_KEY },
  body: JSON.stringify({ data: updatedConfig })
});

Clone this wiki locally