A beautiful, customizable service dashboard for Nextcloud.
LinkBoard turns your Nextcloud into a personal homelab dashboard. Organize all your self-hosted services in one place — with live status checks, real-time widgets, custom icons, and a fully configurable layout. Inspired by Gethomepage, but deeply integrated into Nextcloud.
![]() |
![]() |
![]() |
![]() |
![]() |
- Service Dashboard – Organize services in categories with drag & drop sorting; sections can be placed side by side in a row or dropped between rows
- Grid Layout – Grafana-style grid layout with free drag, resize, and placement of cards within categories
- Configurable Grid – Set grid granularity per category (6, 12, or 24 columns) with auto-arrange and row-height options
- Edit Mode – Lock/unlock edit mode toggle to prevent accidental changes
- Status Checks – Live health checks with dot or border indicators; manual refreshes are rate-limited, deduplicated, runtime-bounded, and prioritize the stalest services
- TLS Policy – Administrators can enforce certificate verification globally or permit per-service exceptions for self-signed homelab services
- Outbound Request Protection – User-configured hosts are validated, pinned to their checked DNS addresses, and prevented from reaching loopback, link-local, multicast, or reserved targets
- Validated Settings – Dashboard settings use a typed server-side allowlist with strict normalization before persistence or import
- Status History – Response time charts, uptime tracking, and a dedicated status overview page
- Offline Notifications – Nextcloud notifications when services go down, with configurable threshold and recovery alerts
- External Notification Channels – 19 providers: Discord, Slack, Telegram, Matrix, Teams, Ntfy, Gotify, Pushover, E-Mail (SMTP), and more, with per-service overrides
- Hardened SMTP – Correct STARTTLS and implicit TLS handling with validated destinations, bounded I/O, and support for ports 25, 465, 587, 1025, and 2525
- 136 Built-in Widgets – Real-time data from Proxmox, Patchman, Immich, Uptime Kuma, and 130+ more; plus an inline-editable Table widget (full list)
- Hardened Widget Proxy – Request URLs and upstream error details are not exposed; batch loads are paginated, time-bounded, rate-limited, deduplicated, and briefly cached
- System Resources – Monitor CPU, memory, disk usage, uptime, and CPU temperature with progress bars
- Category Spacers – Decorative separator categories with multiple styles (solid, dashed, dotted, dots, stars, and more)
- Flexible Icons – Upload custom images (PNG, JPEG, WebP, GIF, ICO), use Material Design Icons (inline SVG) by name in either kebab-case (
mdi-cloud) or camelCase (mdiCloud), or any URL - Theming – Dark, light, or auto mode with custom background images and blur effects
- Card Styles – Glass, Solid, Flat, or Transparent card backgrounds
- Display Modes – Show services as cards or as a compact single-line list, with the title, URL, or both per row; list rows can be reordered and moved between categories via drag & drop in edit mode
- Link Target – Open service links in a new tab, the same tab, or configure it per service
- Per-Card Scrollbar Toggle – Hide scrollbars by default for a cleaner look; enable them per card when needed (content stays scrollable either way)
- Configurable Layout – Adjust columns, card styles, search bar, and more
- Import / Export – YAML & JSON support, compatible with Gethomepage services.yaml
- Keyboard Shortcuts – Quick access via
/,E,R,Esc(see below) - Multi-Language – Full i18n support with 57 languages
- Per-User – Each Nextcloud user gets their own private dashboard
- Global Board – Admins can designate one user's board as a shared read-only dashboard for all users
- Group Restriction – Optionally restrict LinkBoard access to specific Nextcloud groups
Want to see what a populated dashboard looks like? Check out
examples/linkboard-example.json —
a ready-to-import sample board with 11 categories, 21 services, and
10 widgets (Proxmox, AdGuard, custom API, system resources, table).
Download the file, then import it via Settings → Import / Export →
Import JSON inside LinkBoard. URLs (192.168.1.1) and auth headers
are placeholders — replace them with your own before importing, or
import as-is and edit each service afterwards.
| Key | Action |
|---|---|
/ |
Focus search bar |
E |
Toggle edit mode |
R |
Refresh all (status checks, widgets, resources) |
Escape |
Close editor / exit edit mode / clear search |
Shortcuts are disabled while typing in input fields.
EandRare ignored when Ctrl/Cmd is held.
- Nextcloud 32, 33, or 34
- PHP 8.2 – 8.5
LinkBoard provides admin settings under Settings > Administration > LinkBoard.
By default, LinkBoard is available to all users. Admins can restrict access to specific Nextcloud groups. Only users in the selected groups (and admins) will see LinkBoard in the navigation.
Admins can enable a global board that replaces all personal dashboards with a single shared board:
- Go to Settings > Administration > LinkBoard
- Enable "Show a global LinkBoard for all users"
- Select a user whose board should be displayed to everyone
- Click Save
When active, all users see the selected user's board in read-only mode. Only admins can edit the global board (add/remove categories and services). Personal boards are preserved and will reappear when the global board is disabled.
LinkBoard uses Nextcloud's background job system for periodic status checks. The minimum check interval is 1 minute, but status checks can only run as often as Nextcloud's cron is triggered.
Most Nextcloud installations use a system cron job that runs every 5 minutes by default. If you need 1-minute status checks, you must ensure the Nextcloud cron runs every minute.
Create the service file /etc/systemd/system/nextcloud-cron.service:
[Unit]
Description=Nextcloud cron.php
After=network.target
[Service]
User=www-data
ExecStart=/usr/bin/php /var/www/nextcloud/cron.phpCreate the timer file /etc/systemd/system/nextcloud-cron.timer:
[Unit]
Description=Run Nextcloud cron.php every minute
[Timer]
OnBootSec=5min
OnUnitActiveSec=1min
Unit=nextcloud-cron.service
[Install]
WantedBy=timers.targetEnable and start the timer:
sudo systemctl daemon-reload
sudo systemctl enable --now nextcloud-cron.timerVerify it's running:
systemctl list-timers | grep nextcloud
# Should show: nextcloud-cron.timer with ~1min intervalIf you prefer a traditional crontab entry:
sudo crontab -u www-data -eAdd this line to run every minute:
* * * * * php /var/www/nextcloud/cron.php
Note: Make sure Settings > Administration > Basic settings > Background jobs is set to Cron in your Nextcloud instance.
Download the latest release tarball and extract it into your Nextcloud apps/ directory:
cd /path/to/nextcloud/apps
tar xzf linkboard.tar.gzThen enable the app:
cd /path/to/nextcloud/
php occ app:enable linkboard- Node.js 20+
- npm
- PHP 8.2+
- Composer
- A Nextcloud development instance
cd /path/to/nextcloud/apps/
git clone https://github.com/tschuegy/linkboard-nextcloud.git linkboard
cd linkboard
composer install
npm install
npm run build
cd /path/to/nextcloud/
php occ app:enable linkboardnpm run watch # Auto-rebuild on changes
npm run build # Production build
npm run lint # Lint check
npm run lint:fix # Auto-fix lint issueslinkboard/
├── appinfo/ # App metadata & routes
├── lib/ # PHP backend
│ ├── Controller/ # REST API controllers
│ ├── Db/ # Entity & mapper classes
│ ├── Service/ # Business logic
│ ├── Widget/ # 136 widget definitions
│ └── Migration/ # Database migrations
├── src/ # Vue.js frontend
│ ├── components/ # Vue components
│ ├── store/ # Pinia state management
│ └── services/ # API client
├── css/ # Global styles
├── img/ # App icon & screenshots
├── l10n/ # Translation files (57 languages)
└── templates/ # PHP templates
All endpoints under /apps/linkboard/api/v1/:
| Endpoint | Methods | Description |
|---|---|---|
/dashboard |
GET | Full dashboard (categories + services + settings) |
/categories |
GET, POST | List / create categories |
/categories/{id} |
GET, PUT, DELETE | Single category CRUD |
/categories/reorder |
PUT | Reorder categories |
/services |
GET, POST | List / create services |
/services/{id} |
GET, PUT, DELETE | Single service CRUD |
/services/reorder |
PUT | Reorder services |
/services/{id}/move/{catId} |
PUT | Move service to category |
/settings |
GET, PUT | User settings |
/icons |
GET, POST | List / upload icons |
/icons/{filename} |
GET, DELETE | Serve / delete icon |
/widgets/catalog |
GET | Available widget types |
/widgets/data |
GET | Fetch a bounded page of widget data (offset, limit; continuation via X-LinkBoard-Widget-Next-Offset) |
/status/{id}/history |
GET | Status history for a service |
/status/history |
GET | Status history for all services |
/resources/{categoryId} |
GET | System resources (CPU, memory, disk) |
AGPL-3.0-or-later




