Do you store Laravel global settings in the config files? Would you want them to be editable without touching the code? Let's build a Settings page where you can change things quickly.

Notice: In this simple tutorial we won't use any packages for this, but at the end, I will give a few additional links for extra resources using packages.
1. Setup new Laravel project
For this tutorial, we will start with a new Laravel project with Laravel Breeze as a starter kit.
laravel new demo-database-settingscd demo-database-settingscomposer require laravel/breezephp artisan breeze:install bladephp artisan migrate
2. DB Structure: Settings Model with Migration and Seeder
php artisan make:model Setting -mcs
Let's add the key and value columns to our migration file. We ensure that the key is always unique and that value can have a null value.
database/migrations/2023_05_12_040715_create_settings_table.php
use Illuminate\Database\Migrations\Migration;use Illuminate\Database\Schema\Blueprint;use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { Schema::create('settings', function (Blueprint $table) { $table->id(); $table->string('key')->unique(); $table->string('value')->nullable(); $table->timestamps(); }); }};
In the model, allow key and value attributes to be mass assignable by adding the $fillable property.
app/Models/Setting.php
namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory;use Illuminate\Database\Eloquent\Model; class Setting extends Model{ use HasFactory; protected $fillable = ['key', 'value'];}
Let's add some initial entries into the seeder:
database/seeders/SettingSeeder.php
namespace Database\Seeders; use App\Models\Setting;use Illuminate\Database\Console\Seeds\WithoutModelEvents;use Illuminate\Database\Seeder; class SettingSeeder extends Seeder{ /** * Run the database seeds. */ public function run(): void { $settings = [ ['key' => 'site_name', 'value' => 'Article about database settings'], ['key' => 'description', 'value' => 'Learn how to manage app settings using database.'], ['key' => 'posts_per_page', 'value' => 10], ['key' => 'users_can_register', 'value' => true], ]; Setting::insert($settings); }}
Make sure you call SettingSeeder by adding it to DatabaseSeeder.
database/seeders/DatabaseSeeder.php
namespace Database\Seeders; // use Illuminate\Database\Console\Seeds\WithoutModelEvents;use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder{ /** * Seed the application's database. */ public function run(): void { $this->call(SettingSeeder::class); }}
Finally, you can run migrations with seeders:
php artisan migrate --seed
3. Controller, Routes, and View
Our Controller will have edit() and update() methods to show form and update values:
app/Http/Controllers/SettingsController.php
namespace App\Http\Controllers; use App\Models\Setting;use Illuminate\Http\Request; class SettingsController extends Controller{ public function edit() { return view('settings', [ 'settings' => Setting::get(['key', 'value']) ]); } public function update(Request $request) { $data = $request->except('_token'); foreach ($data as $key => $value) { Setting::where('key', $key)->update(['value' => $value]); } return to_route('settings.edit') ->withStatus('Settings updated successfully.'); }}
Create the settings blade view with the following...
Premium Members Only
This advanced tutorial is available exclusively to Laravel Daily Premium members.
Already a member? Login here
Premium membership includes:
Comments & Discussion
This is great, is there a way to split out the settings into different tabs? If I added in the sites social media links, I would like to add this to a tab in the admin settings called Social.
There is a couple of ways to do that:
- Create another page with the social settings. This is a simple repeating of the settings page, but only with social information. Separate controller to load the page and update the data.
- Use JavasScript to add "tabs" on your page. Then, you can handle it as a separate form or as a same one with different fields - that's up to you
I can't tell for sure which is best, but I don't see anything limiting this
Povilas you forgot to mention to run the below command to regenerate the autoload file after updating composer.json:
composer dump-autoload