IntraVox is a modern intranet application for Nextcloud that provides SharePoint-like content management capabilities. This document describes the technical architecture.
+------------------------------------------------------------------+
| Nextcloud Server |
| +--------------------------------------------------------------+ |
| | IntraVox App | |
| | +----------------+ +----------------+ +----------------+ | |
| | | Vue.js SPA | | PHP Backend | | GroupFolder | | |
| | | (Frontend) |->| (API + Logic) |->| Integration | | |
| | +----------------+ +----------------+ +----------------+ | |
| +--------------------------------------------------------------+ |
| | |
| v |
| +--------------------------------------------------------------+ |
| | IntraVox GroupFolder | |
| | +------------+ +------------+ +------------------------+ | |
| | | Pages | | Navigation | | Images & Attachments | | |
| | | (JSON) | | (JSON) | | (files) | | |
| | +------------+ +------------+ +------------------------+ | |
| +--------------------------------------------------------------+ |
+------------------------------------------------------------------+
IntraVox is an organizational communication platform — it publishes company news, team updates, shared resources, and data from external systems to a broad audience. This is fundamentally different from the Nextcloud Dashboard, which is a personal productivity overview showing each user their own mail, tasks, files, and notifications.
This distinction extends to external system integrations. Many systems that IntraVox connects to — OpenProject, Jira, Canvas LMS, Moodle — also have dedicated Nextcloud integration apps. These serve different purposes:
| Nextcloud integration apps | IntraVox Feed Widget | |
|---|---|---|
| Audience | Individual user (my tasks, my files) | Team or department (shared overview) |
| Purpose | Take action (link files, create items) | Build awareness (see what's happening) |
| Context | Dashboard widget, search, file sidebar | Embedded in intranet page alongside news, calendar, people |
| Visibility | Only the authenticated user | Everyone with page access, including public shares |
| Data scope | Personal (security-trimmed per user) | Organizational (shared view or per-user via OAuth/OIDC) |
These are complementary, not competing. An organization can use integration_openproject for individual developers to link Nextcloud files to work packages, while simultaneously using IntraVox's Feed Widget to show a project status overview on a department intranet page — visible to managers, stakeholders, and team members who don't have OpenProject accounts.
See the Feed Widget documentation for detailed guidance on when to use which approach.
| Layer | Technology |
|---|---|
| Frontend | Vue.js 3, Vue Router, Pinia (state management) |
| Backend | PHP 8.x, Nextcloud App Framework |
| Storage | Nextcloud Files API, GroupFolders |
| Permissions | GroupFolder ACL, Nextcloud Permissions |
| Build | Webpack, npm |
| i18n | Nextcloud L10N, Transifex |
intravox/
├── appinfo/
│ ├── info.xml # App metadata
│ └── routes.php # API route definitions
├── css/
│ └── *.css # Stylesheets
├── img/
│ └── *.svg # App icons
├── js/
│ └── *.js # Compiled JavaScript (build output)
├── l10n/
│ ├── *.js # Compiled translations
│ └── *.json # Translation source files
├── lib/
│ ├── Controller/ # API Controllers
│ │ ├── ApiController.php
│ │ ├── FooterController.php
│ │ ├── NavigationController.php
│ │ └── PageController.php
│ ├── Service/ # Business Logic
│ │ ├── FooterService.php
│ │ ├── NavigationService.php
│ │ ├── PageService.php
│ │ ├── PermissionService.php
│ │ └── SetupService.php
│ └── AppInfo/
│ └── Application.php
├── src/
│ ├── components/ # Vue components
│ ├── views/ # Page views
│ ├── stores/ # Pinia stores
│ ├── App.vue # Root component
│ └── main.js # Entry point
├── templates/
│ └── index.php # Main template
└── demo-data/
├── nl/ # Dutch demo content
├── en/ # English demo content
├── de/ # German demo content
└── fr/ # French demo content
Handles page CRUD operations:
- Load pages from JSON files
- Save page content
- Manage page hierarchy (nested pages)
- Image and attachment handling
Manages the navigation structure:
- Load/save navigation configuration
- Support for megamenu and dropdown navigation types
- Multi-level navigation items
Handles footer content per language.
Integrates with GroupFolder permissions:
- Read permissions from GroupFolder ACL
- Check user access to specific paths
- Filter content based on permissions
Handles initial app setup:
- Creates IntraVox GroupFolder if not exists
- Initializes folder structure
Main application shell with:
- Navigation component
- Router view for page content
- Footer component
Renders the navigation menu:
- Megamenu support
- Dropdown menus
- Language switcher
- Mobile responsive
Displays page content:
- Renders widgets (text, images, links, etc.)
- Edit mode with drag-and-drop
- Row and column layouts
WYSIWYG page editor:
- Widget palette
- Drag-and-drop widget placement
- Real-time preview
- Save/cancel functionality
{
"uniqueId": "page-uuid-here",
"title": "Page Title",
"language": "en",
"layout": {
"columns": 1,
"rows": [
{
"columns": 2,
"backgroundColor": "",
"widgets": [
{
"type": "heading",
"column": 1,
"order": 1,
"content": "Welcome",
"level": 1
},
{
"type": "text",
"column": 1,
"order": 2,
"content": "Page content here..."
}
]
}
],
"sideColumns": {
"left": { "enabled": false, "widgets": [] },
"right": { "enabled": false, "widgets": [] }
}
}
}| Type | Description |
|---|---|
| heading | H1-H6 headings |
| text | Rich text content (Markdown) |
| image | Image with alt text, optional clickable link (internal page or external URL) |
| video | Embedded video from YouTube, Vimeo, PeerTube, or local upload |
| links | Link collection (cards or list) |
| divider | Horizontal separator |
{
"type": "megamenu",
"items": [
{
"id": "nav_home",
"title": "Home",
"uniqueId": "page-uuid",
"url": null,
"target": null,
"children": []
}
]
}GET /api/page/{uniqueId}- Get page by IDPUT /api/page/{uniqueId}- Update pagePOST /api/page- Create new pageDELETE /api/page/{uniqueId}- Delete pageGET /api/pages/{language}- List pages for language
GET /api/navigation/{language}- Get navigationPUT /api/navigation/{language}- Update navigation
GET /api/footer/{language}- Get footerPUT /api/footer/{language}- Update footer
GET /api/setup- Check setup statusPOST /api/setup- Run setup
All content is stored in the IntraVox GroupFolder:
IntraVox/
├── {language}/
│ ├── navigation.json
│ ├── footer.json
│ ├── home.json
│ ├── _media/
│ │ └── *.jpg, *.png, *.mp4, ...
│ └── {section}/
│ ├── {page}.json
│ ├── _media/
│ └── {subpage}/
│ └── ...
The _media/ folder stores images, videos, and other media files. Local video uploads are stored here alongside images.
- Version control through Nextcloud versioning
- Easy backup and migration
- No database tables required
- Content editable via Nextcloud Files app
- Integrates with Nextcloud sharing
IntraVox supports multiple languages:
- Each language has its own folder structure
- Navigation and footer are per-language
- Pages can link to translations via uniqueId
- UI translations via Nextcloud L10N system
See AUTHORIZATION.md for detailed permission documentation.
Key points:
- Uses GroupFolder permissions
- Supports ACL for fine-grained control
- Permissions checked at API and UI level
- Navigation filtered based on access
IntraVox uses a multi-layer caching strategy and resilience patterns to support large deployments (up to 10k users, 5k pages):
- Distributed caching (Redis/APCu) for page trees, feed results, and people filter results
- Singleflight locks to prevent thundering herd on external feed sources
- Circuit breaker to handle failing external sources gracefully
- Background feed refresh via Nextcloud cron to keep caches warm
- Page metadata database index for fast listing, tree, and search operations
- Bundle splitting (217 KB main + lazy-loaded editor and widgets)
- Progressive rendering in tree components (50 items per batch)
Rate limiting, audit logging, GDPR user deletion, and a health check endpoint provide enterprise-grade operational security.
See Scalability & Enterprise Readiness for full details.
# Install dependencies
npm install
# Development build with watch
npm run dev
# Production build
npm run build
# Create release tarball
./create-release.shSee README.md for installation instructions. Key steps:
- Install via Nextcloud App Store or manually
- Enable the app
- GroupFolder "IntraVox" is created automatically
- Add groups to the GroupFolder
- Import demo data or start creating pages
IntraVox can integrate with MetaVox for enhanced navigation:
- Respects MetaVox department structure
- Uses MetaVox nav color settings
- Syncs navigation styles
- Automatic GroupFolder creation
- ACL permission reading
- File storage within GroupFolder
- Uses Nextcloud theming (colors, logo)
- Integrates with Nextcloud Files
- Supports Nextcloud versioning
- Uses Nextcloud authentication