spatie/laravel-settings
Strongly typed application settings for Laravel. Define settings classes with typed properties, store values in a repository (database, Redis, etc.), inject settings via the container, and update them easily with $settings->save().
Installation
Run composer require spatie/laravel-settings and publish the migrations and config:
php artisan vendor:publish --provider="Spatie\LaravelSettings\LaravelSettingsServiceProvider" --tag="migrations"
php artisan vendor:publish --provider="Spatie\LaravelSettings\LaravelSettingsServiceProvider" --tag="config"
Run migrations:
php artisan migrate
Create a Settings Class Use the Artisan command to scaffold a new settings class:
php artisan make:setting GeneralSettings --group=general
This generates a class like:
class GeneralSettings extends Settings {
public string $site_name;
public bool $site_active;
public static function group(): string {
return 'general';
}
}
Register the Class
Add the class to config/settings.php under the settings array:
'settings' => [
GeneralSettings::class,
],
Create a Migration Define default values for your settings:
php artisan make:settings-migration CreateGeneralSettings
Populate defaults in the migration:
public function up(): void {
$this->migrator->add('general.site_name', 'MyApp');
$this->migrator->add('general.site_active', true);
}
Run the migration:
php artisan migrate
First Usage Inject the settings class into a controller or service:
class HomeController {
public function index(GeneralSettings $settings) {
return view('home', [
'site_name' => $settings->site_name,
]);
}
}
public function updateSettings(GeneralSettings $settings, Request $request) {
$settings->site_name = $request->input('site_name');
$settings->save();
}
config/settings.php under default_repository.repository():
public static function repository(): ?string {
return 'redis';
}
config/settings.php:
'cache' => [
'enabled' => true,
'store' => 'redis',
'ttl' => 60, // Cache TTL in minutes
],
group() to logically separate settings (e.g., general, payment, notifications).class PaymentSettings extends Settings {
public static function group(): string {
return 'payment';
}
}
class GeneralSettingsRequest extends FormRequest {
public function rules(): array {
return [
'site_name' => 'required|string|max:255',
'site_active' => 'boolean',
];
}
}
$settings = app(GeneralSettings::class);
$settings->site_active = false;
$settings->save();
Missing Migrations:
php artisan migrate after modifying settings migrations.Circular Dependencies:
app(GeneralSettings::class)) sparingly.Repository Mismatches:
config/settings.php or use the default.Cache Stale Data:
'enabled' => false) or manually clear the cache:
php artisan cache:clear
Type Safety:
Check Repository Contents:
php artisan tinker
>>> \Spatie\LaravelSettings\Settings::all();
Log Settings Updates:
$settings->save();
\Log::info('Settings updated', ['group' => $settings->group(), 'data' => $settings->toArray()]);
Validate Migrations:
Custom Repositories:
Spatie\LaravelSettings\SettingsRepositories\SettingsRepository to support new storage backends (e.g., S3, DynamoDB).Custom Casts:
config/settings.php:
'global_casts' => [
MyCustomClass::class => MyCustomCast::class,
],
Event Listeners:
use Spatie\LaravelSettings\Events\SettingsUpdated;
SettingsUpdated::dispatch($settings);
Custom Encoders/Decoders:
'encoder' => function ($value) {
return serialize($value);
},
'decoder' => 'unserialize',
Batch Updates:
\DB::transaction(function () use ($settings) {
$settings->property1 = $value1;
$settings->property2 = $value2;
$settings->save();
});
Selective Loading:
Settings::get() to fetch only specific properties:
$siteName = Settings::get(GeneralSettings::class, 'site_name');
Disable Caching in Development:
'enabled' => false in config/settings.php for faster iteration.Feature Flags:
class FeatureFlags extends Settings {
public bool $new_ui_enabled;
public bool $experimental_api;
public static function group(): string {
return 'features';
}
}
Usage:
if (app(FeatureFlags::class)->new_ui_enabled) {
// Enable new UI
}
Multi-Tenant Settings:
class TenantSettingsMiddleware {
public function handle($request, Closure $next) {
$settings = app(TenantSettings::class)->forTenant(auth()->id());
// ...
}
}
Environment-Specific Settings:
.env or config files:
if (app()->environment('staging')) {
$settings->debug_mode = true;
}
How can I help you explore Laravel packages today?