tomatophp/filament-settings-hub
Manage your Filament app settings with a GUI and helper functions. Install via Composer, run the install command, and register the plugin in your panel provider. Use the setting() helper to read values, and register new settings pages using the SettingHold facade.
Installation
composer require tomatophp/filament-settings-hub
Run the installer (publishes config, migrations, and assets in one step):
php artisan filament-settings-hub:install
Then run migrations:
php artisan migrate
Tip: The
filament-settings-hub:installcommand is idempotent as of v5.0.1 — it publishes each settings migration only once, so re-running it is safe.
Register the Plugin
Add to app/Providers/Filament/AdminPanelProvider.php:
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
\TomatoPHP\FilamentSettingsHub\FilamentSettingsHubPlugin::make()
->allowColorSettings(), // optional: enables the site color page (v5.0.1+)
]);
}
First Use Case Define a setting group in a migration or via the GUI:
use TomatoPHP\FilamentSettingsHub\Database\SettingGroup;
SettingGroup::create([
'name' => 'App Configuration',
'slug' => 'app-config',
'description' => 'Global app settings',
]);
Access settings in code (the setting() helper is the lightest path):
$value = setting('app-config.some_setting');
// or via the facade
$value = \TomatoPHP\FilamentSettingsHub\Facades\SettingsHub::get('app-config.some_setting');
If you enabled ->allowColorSettings(), you get a dedicated site color page out of the box. After running install + migrate, read the colors anywhere:
$primary = setting('site_primary_color');
$secondary = setting('site_secondary_color');
$tertiary = setting('site_tertiary_color');
Colors are stored in their own site_colors settings group, so this is fully additive — existing apps are unaffected unless they opt in.
GUI-Driven Configuration
/settings-hub route.app-config, payment-gateway, site_colors) and keys (e.g., max_upload_size, stripe_api_key, site_primary_color).Dynamic Form Fields
Leverage the SettingField model to define custom fields for each setting key:
use TomatoPHP\FilamentSettingsHub\Database\SettingField;
SettingField::create([
'group_id' => 1, // app-config group
'key' => 'max_upload_size',
'label' => 'Max Upload Size (MB)',
'type' => 'number',
'default' => 10,
'validation_rules' => 'required|min:1',
]);
Accessing Settings
$value = setting('app-config.max_upload_size');
$value = SettingsHub::get('app-config.max_upload_size');
$this->app->bind(SettingsHub::class, function ($app) {
return new SettingsHub(config('filament-settings-hub'));
});
Site Color Settings (v5.0.1+)
->allowColorSettings() on the plugin.php artisan filament-settings-hub:install && php artisan migrate to create the site_colors group and its fields.// app/Providers/AppServiceProvider.php (boot)
View::share('brand', [
'primary' => setting('site_primary_color', '#2563eb'),
'secondary' => setting('site_secondary_color', '#7c3aed'),
'tertiary' => setting('site_tertiary_color', '#0ea5e9'),
]);
site_colors group, they don't collide with existing groups.Environment-Based Fallbacks
Use the fallback config option to default to .env values:
// config/filament-settings-hub.php
'fallbacks' => [
'app-config.max_upload_size' => env('MAX_UPLOAD_SIZE', 10),
'site_colors.site_primary_color' => env('BRAND_PRIMARY', '#2563eb'),
],
Caching Enable Redis caching for performance:
// config/filament-settings-hub.php
'cache' => [
'enabled' => true,
'driver' => 'redis',
'prefix' => 'settings_hub_',
],
public static function getFilamentSettingsHubAccess(): array
{
return ['admin']; // Only users with 'admin' role can access
}
Note: the color page inherits the same policy gate — restrict it with the same rules you use for the main settings hub.
use TomatoPHP\FilamentSettingsHub\Events\SettingUpdated;
SettingUpdated::listen(function (SettingUpdated $event) {
Log::info("Setting updated: {$event->key}", [
'value' => $event->payload,
'group' => $event->group ?? null,
]);
});
Route::middleware('auth:sanctum')->get('/api/settings/{group}', function (string $group) {
return SettingsHub::getGroup($group);
});
A public /api/settings/site_colors endpoint is convenient for theming frontends.Migration Conflicts
setting_groups or setting_fields tables, ensure they match the package’s schema:
Schema::create('setting_groups', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug')->unique();
$table->text('description')->nullable();
$table->timestamps();
});
Duplicate Migrations on Reinstall
filament-settings-hub:install could publish the same migration multiple times. This is fixed — but if you upgraded an existing app, check database/migrations for leftover *_site_colors* duplicates before migrating and delete stale files.Color Page Not Appearing
->allowColorSettings() on the plugin. If colors are missing at runtime, verify the site_colors group exists in the DB (SettingGroup::where('slug','site_colors')->first()), and that you ran migrate after install.setting('site_primary_color'), pass a default (e.g. setting('site_primary_color', '#2563eb')) so your theme never renders with null.Caching Stale Data
php artisan cache:clear
php artisan view:clear
SettingsHub::forget($key) to manually invalidate a single setting (particularly relevant for colors cached in Redis).Permission Denied
filament-settings-hub plugin is registered in the correct panel provider.resources and pages for the plugin route.Field Type Limitations
rich_text, color_picker) require additional setup:
// config/filament-settings-hub.php
'custom_field_types' => [
'rich_text' => \TomatoPHP\FilamentSettingsHub\FieldTypes\RichTextField::class,
],
Log Settings Enable debug mode in config:
'debug' => true,
Logs will appear in storage/logs/laravel.log.
Query Builder Inspect raw queries with Laravel Debugbar or Tinker:
php artisan tinker
>>> \TomatoPHP\FilamentSettingsHub\Database\Setting::query()->toSql();
Verify Install State Check what the installer produced:
php artisan filament-settings-hub:install --help
Inspect the site_colors group after migration:
php artisan tinker
>>> \TomatoPHP\FilamentSettingsHub\Database\SettingGroup::where('slug','site_colors')->with('fields')->first();
Seeding Data
Use the SettingsHubSeeder for testing:
use TomatoPHP\FilamentSettingsHub\Database\SettingGroup;
use TomatoPHP\FilamentSettingsHub\Database\SettingField;
SettingGroup::create(['name' => 'Test', 'slug' => 'test']);
SettingField::create([
'group_id' => 1,
'key' => 'test_setting',
'type' => 'text',
'default' => 'default_value',
]);
Custom Field Types
Extend the SettingFieldType interface:
namespace App\FilamentSettingsHub;
use TomatoPHP\FilamentSettingsHub\Contracts\SettingFieldType;
class CustomFieldType implements SettingFieldType
{
public function getWidget(): string
{
return 'custom-widget';
}
public function getValidationRules(): array
{
return ['required'];
}
}
Register in config:
'custom_field_types' => [
'custom' => \App\FilamentSettingsHub\CustomFieldType::class,
],
Extend Color Settings
Use the site_colors group as a model — add your own fields to it (e.g. site_accent_color) and read them with setting('site_accent_color'). Because it's an isolated group, you can layer extra colors without touching existing config.
Override Default Views Publish and modify the package’s views:
php artisan vendor:publish --provider="TomatoPHP\FilamentSettingsHub\FilamentSettingsHubServiceProvider" --tag="filament-settings-hub-views"
Edit files in resources/views/vendor/filament-settings-hub/.
API Resources Create a custom API resource for settings:
namespace App\Http\Resources;
use TomatoPHP\FilamentSettingsHub\Database\SettingGroup;
use Illuminate\Http\Resources\Json\JsonResource;
class SettingGroupResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'fields' => $this->fields->map(fn ($field) => [
'key' => $field->key,
'value' => setting("{$this->slug}.{$field->key}"),
]),
];
}
}
Multi-Tenant Support
Scope settings by tenant using Laravel’s tenant() helper:
$tenantId = tenant('id');
$value = SettingsHub::where('tenant_id', $tenantId)->get('app-config.theme');
How can I help you explore Laravel packages today?