Customization
Learn how to brand, extend, and customize Automation Hub — from simple logo changes to building your own custom modules with the Module SDK.
Branding
Customize the look and feel of your Automation Hub instance to match your organization's brand identity.
Logo & Favicon
Navigate to Settings > General to upload:
- Logo — Recommended size: 200x200px. Formats: PNG, JPG, SVG. Displayed in the sidebar, email templates, and exported reports.
- Favicon — Size: 32x32 or 64x64. Displayed in browser tabs.
- Brand Name — The organization name shown in the sidebar header and page titles.
Landing Page Branding
Navigate to Settings > Landing Page for additional branding options specific to the public-facing page:
- Separate logo upload for the landing page header
- Custom hero text, tagline, and CTA buttons
- Dark/light theme toggle
- All content translatable in 4 languages (EN/ES/FR/AR)
Landing Page Editor
The landing page admin editor at Settings > Landing Page provides full control over all public-facing sections:
- Hero Section — Headline, subtitle, primary/secondary CTA buttons with links
- Features Section — Add/remove/reorder feature cards with icon, title, description
- Modules Section — Showcase which modules are available
- Pricing Section — Define pricing tiers with feature checklists
- About Section — Rich text content area
- CTA Section — Bottom banner with headline and button
- Footer — Links, copyright text, social media links
Each section supports:
- Toggle visibility (show/hide)
- Content in all 4 supported languages
- Live preview before publishing
Adding Translations
Automation Hub uses i18next for frontend internationalization. Translation files are JSON files located at:
resources/js/locales/
├── en/
│ └── common.json # English translations
├── es/
│ └── common.json # Spanish translations
├── fr/
│ └── common.json # French translations
└── ar/
└── common.json # Arabic translations
Translation File Format
Each common.json file is a flat or nested JSON object with translation keys:
{
"dashboard": {
"title": "Dashboard",
"welcome": "Welcome back, {{name}}",
"totalWorkflows": "Total Workflows",
"totalExecutions": "Total Executions"
},
"workflows": {
"title": "Workflows",
"create": "Create Workflow",
"edit": "Edit Workflow",
"delete": "Delete Workflow",
"confirmDelete": "Are you sure you want to delete this workflow?"
},
"common": {
"save": "Save",
"cancel": "Cancel",
"delete": "Delete",
"loading": "Loading..."
}
}
How to Add a New Key
- Add the key to all 4 locale files (en, es, fr, ar)
- Use the
useTranslationhook in your React component:
import { useTranslation } from 'react-i18next';
export function MyComponent() {
const { t } = useTranslation();
return (
<div>
<h1>{t('myModule.title')}</h1>
<p>{t('myModule.description', { count: 5 })}</p>
</div>
);
}
Adding a New Language
- Create a new folder:
resources/js/locales/{locale}/common.json - Copy the English file as a base and translate all keys
- Register the locale in the i18n configuration file
- Add RTL support if needed (set
dir: 'rtl'in the locale config)
Creating a Custom Module
Automation Hub provides a Module SDK that allows you to create custom modules with their own node types, routes, and business logic.
Step 1: Create the Module Folder
mkdir -p app/Modules/YourModule
Step 2: Create module.json Manifest
{
"name": "YourModule",
"slug": "your-module",
"version": "1.0.0",
"description": "A custom module for Automation Hub",
"author": "Your Name",
"enabled": true,
"provider": "App\\Modules\\YourModule\\YourModuleProvider",
"nodes": [
"your_custom_action"
],
"settings": {
"api_key": {
"type": "encrypted",
"label": "API Key",
"required": true
}
}
}
Step 3: Create the Module Service Provider
<?php
namespace App\Modules\YourModule;
use App\Core\Modules\ModuleSDK;
class YourModuleProvider extends ModuleSDK
{
/**
* Register node executors provided by this module.
*/
public function registerNodeExecutors(): array
{
return [
'your_custom_action' => \App\Modules\YourModule\Nodes\YourCustomActionExecutor::class,
];
}
/**
* Register module-specific routes.
*/
public function registerRoutes(): void
{
// Register API routes, webhook endpoints, etc.
}
/**
* Boot the module (run after all providers are registered).
*/
public function boot(): void
{
// Publish config, migrations, views, etc.
}
}
Step 4: Create a Node Executor
<?php
namespace App\Modules\YourModule\Nodes;
use App\Core\Contracts\NodeExecutorInterface;
use App\Core\DTOs\NodeExecutionContext;
use App\Core\DTOs\NodeExecutionResult;
class YourCustomActionExecutor implements NodeExecutorInterface
{
/**
* Execute the node logic.
*
* @param NodeExecutionContext $context Contains input data, config, and credentials
* @return NodeExecutionResult The output to pass to downstream nodes
*/
public function execute(NodeExecutionContext $context): NodeExecutionResult
{
// Access input from previous nodes
$inputData = $context->getInputData();
$name = $inputData['name'] ?? 'World';
// Access module settings (decrypted automatically)
$apiKey = $context->getModuleSetting('api_key');
// Perform your custom logic
$result = [
'greeting' => "Hello, {$name}!",
'timestamp' => now()->toISOString(),
];
return NodeExecutionResult::success($result);
}
/**
* Describe the node for the visual canvas (inputs, outputs, config fields).
*/
public static function describe(): array
{
return [
'type' => 'your_custom_action',
'label' => 'Your Custom Action',
'description' => 'Performs a custom action with your external service',
'category' => 'your-module',
'icon' => 'zap',
'inputs' => [
[
'key' => 'name',
'label' => 'Name',
'type' => 'string',
'required' => true,
'description' => 'The name to greet',
],
],
'outputs' => [
['key' => 'greeting', 'type' => 'string'],
['key' => 'timestamp', 'type' => 'string'],
],
'config' => [],
];
}
}
Step 5: Register the Module
Register your module using the artisan command:
php artisan module:discover
Alternatively, register it manually in the module configuration file.
Project Folder Structure
automation-hub/
├── app/
│ ├── Core/ # Core platform logic
│ │ ├── Contracts/ # Interfaces (NodeExecutorInterface, etc.)
│ │ ├── DTOs/ # Data Transfer Objects
│ │ ├── Engine/ # Workflow execution engine
│ │ ├── Events/ # Domain events & event bus
│ │ ├── Models/ # Eloquent models (Workflow, Execution, etc.)
│ │ ├── Modules/ # Module SDK base classes
│ │ └── Services/ # Core services (audit, auth, etc.)
│ ├── Modules/ # Feature modules (self-contained)
│ │ ├── Email/ # Email module (SMTP, Resend)
│ │ ├── WhatsApp/ # WhatsApp module (Meta, Twilio)
│ │ ├── AI/ # AI module (Claude, OpenAI)
│ │ ├── Courier/ # Courier module (Deprixa Plus)
│ │ └── Notifications/ # Notifications module
│ ├── Shared/ # Shared utilities, traits, helpers
│ └── Http/ # Controllers, Middleware, Requests
├── resources/
│ └── js/
│ ├── Pages/ # Inertia.js React pages
│ ├── Components/ # Reusable React components
│ ├── Hooks/ # Custom React hooks
│ ├── Layouts/ # Page layouts
│ └── locales/ # i18n translation files (en/es/fr/ar)
├── routes/ # Web and API route definitions
├── database/
│ ├── migrations/ # Database migrations
│ └── seeders/ # Data seeders (templates, etc.)
├── config/ # Configuration files
├── tests/ # Automated tests (274 tests)
└── public/ # Web root (compiled assets)
Modular Architecture
Each module in app/Modules/ is self-contained with its own providers, node executors, models, and configuration. This makes it easy to add, remove, or replace modules without affecting the core platform.