⭐ Star this repo if it helps you - it truly motivates us to do more. 🙏😊
DB Config is a Filament plugin that provides a simple, database-backed key/value store for application settings and editable content.
It’s ideal both for storing configuration (like site name, contact info, labels) and for managing page sections (homepage hero, landing blocks, about text, etc.) without the need for a full CMS.
It provides a clean set of simple helpers for reading and writing values, with transparent caching under the hood, and persists data as JSON in a dedicated table.
It is framework-friendly and requires no custom Eloquent models in your app.
Install the package via Composer:
composer require inerba/filament-db-config
Publish the assets (Configuration and Migration):
php artisan vendor:publish --tag="db-config-migrations"
Run the migration:
php artisan migrate
This command executes the migration file that you just published, creating the db_config
table (or the custom table name you defined in the config file) in your database. Your package is now ready to use!
[!TIP] If you want to use a custom table name instead of
db_config
, edit the configuration fileconfig/db-config.php
before running the migration. See the Configuration section for details.
Get up and running in just a few steps:
Generate Your First Settings Page
php artisan make:db-config Website
This command creates a new Filament page (e.g., App/Filament/Pages/WebsiteSettings.php). You can repeat this step for more pages as needed.
[!NOTE] The generator will automatically add the “Settings” suffix to the page name for consistency (e.g., WebsiteSettings), but you can use any group name you wish.
Define Your Fields
Open the generated page and customize the form() method with your desired fields:
public function form(Form $form): Form{ return $form ->components([ TextInput::make('site_name')->label('Site Name'), TextInput::make('contact_email')->label('Contact Email'), Toggle::make('maintenance_mode')->label('Maintenance Mode'), ]) ->statePath('data');}
[!NOTE] You may use any Filament form fields or layout components - including third-party ones - to build your settings and content pages, giving you full flexibility in how data is structured and edited.
Save and Edit Settings from the Admin Panel
You can now edit these settings directly in your Filament admin panel—no extra boilerplate needed.
Use Your Settings Anywhere
Retrieve your configuration values easily:
In PHP:
$siteName = db_config('website.site_name', 'Default Site Name');
In Blade:
<h1>{{ db_config('website.site_name', 'Default Site Name') }}</h1> <!-- or --> <h1>@db_config('website.site_name', 'Default Site Name')</h1>
That’s it! 🎉
Define your fields, save from the admin panel, and access your settings anywhere in your Laravel app.
You can customize the behavior of the package by publishing the configuration file:
php artisan vendor:publish --tag="db-config-config"
Table Name: By default, settings are stored in the db_config table. You can change this by modifying the table_name value. This is useful to avoid collisions or to follow a specific naming convention.
'table_name' => 'db_config',
Cache Behavior: The package uses caching to minimize database queries. You can fine-tune the cache settings.
prefix: All cache keys generated by the package will use this prefix. Changing this can prevent collisions with other cache keys in your application.
ttl: Defines the cache lifetime in minutes. By default, it's null, which means settings are cached forever. You can specify a number of minutes to have the cache expire periodically.
'cache' => [ 'prefix' => 'my-app-settings', 'ttl' => 60, // Cache for 1 hour],
DB Config ships with an Artisan generator and an abstract Page class to quickly scaffold Filament settings pages.
php artisan make:db-config
Arguments can be omitted: if you don’t provide them, the command will enter interactive mode and prompt you for the group name (name) and, optionally, the panel (panel). You can also pass them on the command line to avoid interactive prompts.
Parameters:
name
: the settings group name (e.g. website
). It is used to generate the view name and the class name (singular, capitalized).panel
(optional): the Filament panel to create the page in (e.g. Admin
). If omitted the default panel is used.Examples:
php artisan make:db-config website # default panelphp artisan make:db-config website admin # specific panel (e.g. Admin)
What is generated:
app/Filament/{Panel}/Pages/{Name}Settings.php
(the class name is the singular form of {name}
+ Settings
, e.g. WebsiteSettings.php
).resources/views/filament/config-pages/{slug-name}-settings.blade.php
(the view name is a slugified version of the name
with a -settings
suffix).Behavior:
Note: the generated class extends Inerba\DbConfig\AbstractPageSettings
and the view is placed under resources/views/filament/config-pages/
.
Page lifecycle and saving:
mount()
, the page loads all settings for the given group (defined by settingName()
) via DbConfig::getGroup()
and fills the page content state.DbConfig::set("{group}.{key}", $value)
for each top-level key present in the page content.Defining the page content:
protected function settingName(): string
to define the group name (e.g. website
).public function content(Schema $schema): Schema
and return your content schema.->statePath('data')
so the page state is bound to the $data
property and saved correctly.Example page content (Filament schema):
use Filament\Forms\Components\TextInput;use Filament\Schemas\Schema; public function content(Schema $schema): Schema{ return $schema ->components([ TextInput::make('site_name')->required(), // ... other inputs ]) ->statePath('data');}
The simplest way to manage values is through the Filament pages scaffolded by DB Config:
you can define the fields you need (text inputs, toggles, repeaters, rich text, even third-party components) and edit them directly in the admin panel.
All changes are saved automatically in the db_config
table and cached for fast access.
For programmatic access, the package also provides simple helpers and static methods:
db_config('website.site_name', 'Default Name');
You can also access values directly inside Blade templates:
@db_config('website.site_name', 'Default Name')
\Inerba\DbConfig\DbConfig::get('website.site_name', 'Default Name');
\Inerba\DbConfig\DbConfig::set('website.site_name', 'Acme Inc.');
\Inerba\DbConfig\DbConfig::getGroup('website');// => [ 'site_name' => 'Acme Inc.', 'contact' => ['email' => 'info@acme.test'] ]
\Inerba\DbConfig\Facades\DbConfig::get('website.site_name');
[!NOTE] these values are not part of Laravel’s config() cache. Always use db_config() or @db_config instead of config(). The
db_config()
helper is auto-registered by the package and is the recommended way to read values in application code.
You can provide default values for your settings page. This is useful for pre-filling the form with sensible defaults when it's accessed for the first time. It guides the user by showing recommended settings, which they can then adjust or save directly to establish a working configuration without manual setup.
To define default values, simply override the getDefaultData() method in your settings page class and return an array of key-value pairs.
Example:
use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Toggle; use Filament\Schemas\Schema; /** * Set the default values to pre-fill the form. * * @return array<string,mixed> */ public function getDefaultData(): array { return [ 'posts_per_page' => 10, 'allow_comments' => true, ]; } public function form(Schema $schema): Schema { return $schema ->components([ TextInput::make('posts_per_page')->required(), Toggle::make('allow_comments'), ]) ->statePath('data'); }}
When the settings page is loaded, the getDefaultData() method provides the initial values to populate the form fields. These defaults are only used if no value for a given field has been previously saved to the database.
It's important to note that these default values are not persistent until the user explicitly clicks the "Save" button.
DB Config uses a group.setting
format for keys, with optional nested sub-keys resolved from JSON.
Example:
// Store a nested structure\Inerba\DbConfig\DbConfig::set('profile.preferences', [ 'theme' => 'dark', 'notifications' => ['email' => true, 'sms' => false],]); // Read a nested value with defaultdb_config('profile.preferences.theme', 'light'); // 'dark' // Read a missing nested valuedb_config('profile.preferences.timezone', 'UTC'); // 'UTC'
Settings are organized by a two-part key: group.setting
, with optional nested sub-keys (e.g. group.setting.nested.key
).
Under the hood:
db_config
), with one row per (group, key)
. The actual settings are stored as a JSON payload in the settings
column.db-config
by default) followed by the group and setting (e.g., db-config.website.site_name
).The db_config
table contains:
id
(bigint, primary key)group
(string)key
(string)settings
(json, nullable)created_at
, updated_at
(timestamps)There is a unique index on (group
, key
). Timestamps are present but not used by the package logic and may remain null depending on your database defaults.
This package stores settings as JSON. Ensure your chosen database supports JSON columns. For SQLite (common in tests), JSON is stored as text and works transparently for typical use cases.
To minimize database traffic, DB Config comes with a powerful caching layer. Here’s how it works:
DbConfig::set()
or the "Save" action on a settings page, the cache for the affected (group, setting)
pair is automatically cleared. This ensures that the next read will fetch the fresh value from the database.ttl
(Time To Live) in minutes in the config/db-config.php
file. If a TTL is set, the package will use a temporary cache that expires after the specified duration.php artisan cache:clear
to reset all cached settings.null
, the default is returned.getGroup()
returns an associative array of all settings for the group, or an empty array if none exist.Both DB Config and the official Spatie Laravel Settings Plugin solve a similar problem - managing application settings in Laravel + Filament - but they take very different approaches.
Spatie Settings focuses on strict typing, validation, and integration with your domain logic, while DB Config is designed to be lightweight, flexible, and quick to set up, even for editable content blocks.
The table below highlights the key differences so you can choose the right tool for your project:
Feature | DB Config | Spatie Laravel Settings Plugin |
---|---|---|
Setup | Ready to use, no extra classes or migrations | Requires a dedicated Settings class for each group, plus migration to register it |
Data storage | Single db_config table with JSON values |
Each group stored as its own settings record (linked to its Settings class) |
Boilerplate | None required | A new PHP class must be created for every settings group |
Access | Dot notation, supports nested keys in JSON | Strongly typed properties defined in the Settings class |
Cache | Built-in, refreshed automatically on write | Built-in, but usually configured explicitly |
Ideal for | Application settings and editable page content (homepage, blocks, texts) | Strictly typed, validated settings tightly bound to app logic |
Content usage | Can store full page sections (homepage, landing, about, etc.) | Not designed for CMS-like use |
Dependencies | No external deps | Requires spatie/laravel-settings |
Choose DB Config if you want:
Choose Spatie Laravel Settings Plugin if you need strict typing, validation, and DTOs as part of your domain logic.
[!CAUTION] DB Config is a place for values you want admins to edit safely at runtime, not for infrastructure secrets (API keys, DB credentials).
Values are not encrypted by default. If you need encryption, apply it before using the package’s helpers to read or write values.
This package comes with a full test suite powered by Pest. To run the tests, first install the development dependencies:
composer install
Then, run the test suite from the root of the project:
./vendor/bin/pest
The package also uses GitHub Actions to automatically run tests on every push and pull request, ensuring that the code remains stable and reliable.
This package follows semantic versioning. Use a version constraint compatible with your Laravel version as shown in the installation section.
The MIT License (MIT). See the LICENSE file for more details.
Francesco is a freelance web developer specializing in tailor-made software with a strong focus on Laravel and Filament. He prioritizes personalization, efficiency, and human connection in every project, creating solutions that are both functional and meaningful. Francesco has worked across a wide range of technologies and initiatives with social and environmental impact. You can learn more about Francesco on his website.