Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nova Tool Settings Laravel Package

marshmallow/nova-tool-settings

A Laravel Nova tool for managing settings for your application and Nova tools. Define settings in code, let users edit them through a clean Nova interface, and retrieve stored values anywhere in your Laravel app, keeping configuration editable without redeploying. Simple to install and integrate.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the package

    composer require marshmallow/nova-tool-settings
    

    Note: the package is archived and pinned to older Nova versions. Before installing, check composer.json in the repo for the laravel/nova constraint and confirm it matches your project. If you're on Nova 4+ you will likely need to fork and bump the constraint.

  2. Publish and run the migration

    php artisan vendor:publish --provider="Marshmallow\NovaToolSettings\ToolServiceProvider"
    php artisan migrate
    

    This creates the storage table the tool reads from. Inspect the published migration first — you want to know the table name (typically settings) so you can write seeders or factories against it.

  3. Register the tool with Nova

    In app/Providers/NovaServiceProvider.php:

    public function tools()
    {
        return [
            new \Marshmallow\NovaToolSettings\NovaToolSettings,
        ];
    }
    

    The tool appears in Nova's sidebar. Open it once before you wire up any settings — an empty tool is the fastest way to confirm routing and the container binding are working.

  4. Define your first setting "from code"

    The package's core idea is that settings are declared in code (so the UI has a schema to render) and persisted in the DB. Look at src/ for the registration entry point — it's usually a service provider or a config-driven list. A minimal definition looks conceptually like:

    Settings::group('General', function ($group) {
        $group->text('site_name', 'Site name', default: config('app.name'));
        $group->textarea('footer_text', 'Footer');
        $group->boolean('maintenance_mode', 'Maintenance mode');
    });
    

    First use case: expose site_name and maintenance_mode, edit them in Nova, then read them in a Blade view or middleware via the package's helper/facade (check src/ for the exact accessor — it varies between Settings::get('site_name') and a Setting::where(...)->first()->value pattern).

Implementation Patterns

Read-through with a helper wrapper. Don't sprinkle raw facade calls across the codebase. Wrap the package in a small app-level SettingsService so you have one place to swap the backend later (this package is archived — you want that seam):

class SettingsService
{
    public function siteName(): string
    {
        return Settings::get('site_name', config('app.name'));
    }

    public function maintenanceMode(): bool
    {
        return (bool) Settings::get('maintenance_mode', false);
    }
}

Group settings by domain. Group definitions by feature (general, mail, integrations, billing) rather than one giant list. The Nova tool renders groups as tabs/sections, and grouping keeps the admin screen navigable as you add settings.

Cache aggressively, invalidate on write. Settings are read on nearly every request. Cache the whole map in a single key and bust it from the write path:

Cache::rememberForever('app.settings', function () {
    return Settings::all()->pluck('value', 'key')->toArray();
});

Then in an observer or a Nova saved hook, call Cache::forget('app.settings'). If you're writing settings from the tool UI, the package may not clear your cache for you — verify and add it yourself.

Seed defaults for CI and fresh installs. Settings "created from code" should also exist as database rows, otherwise a fresh deploy renders empty. Write a seeder that iterates your definitions and inserts defaults with updateOrCreate, so re-running is safe.

Gate the tool behind a policy. Admins-only is the common case. Check whether the tool supports Nova's canSee / authorize; if not, gate the tool's route with a middleware or a Nova gate in Nova::tools([...]) via a conditional.

Environment overrides. For settings that differ per environment (e.g. mail_from, support_email), prefer config + env and expose only the settings that genuinely need runtime editing. Global settings tools invite people to put secrets in the database — avoid that for credentials.

Pair with feature-flag style reads. A boolean settings row is a cheap feature flag: if (app(SettingsService::class)->maintenanceMode()) { abort(503); } in middleware. It's a good first integration because it exercises the full read→cache→UI loop end to end.

Gotchas and Tips

  • It's archived — treat it as a fork candidate. With 2 stars, zero dependents, and no maintenance, assume you will own the code. Fork it internally on day one so you can patch Nova compatibility and security fixes without waiting for upstream.
  • Nova version drift is the #1 failure mode. Nova's tool API (route registration, booted vs boot, component registration) changed between v3 and v4. If the tool installs but the sidebar entry 404s or renders blank, suspect the Nova constraint first — check composer.lock after install.
  • Migration table naming collisions. Confirm the published migration's table name doesn't clash with an existing settings table from spatie/laravel-settings or similar. Rename the table and the model's $table if needed.
  • Watch for raw string storage. Values are usually stored as text. Cast on read ((bool), (int), json_decode) at your service layer — don't rely on the package's casting, especially if it was written for an older Laravel that handled model casts differently.
  • Debugging empty values: the fastest check is a tinker query on the underlying table (Setting::all()). If the row is missing, the code definition never ran — check that your service provider is auto-discovered or registered in config/app.php, and that it runs after the database is available (don't query during register()).
  • Extension points are limited. The tool is thin; the practical extension surface is: (a) subclasses of the tool class overriding cards()/fields(), and (b) a custom Nova resource if you outgrow the built-in screen. Prefer option (b) once you need validation rules, field-level permissions, or audit logging — retrofitting those onto a single-screen tool is more work than writing a Nova resource yourself.
  • Audit trail. There's almost certainly no "who changed what when" tracking. If settings affect production behaviour, wrap writes in an observer that logs to your activity log — otherwise a broken maintenance-mode toggle is undebuggable.
  • Test the read path, not just the UI. A simple feature test that seeds a setting, hits the app, and asserts the rendered output catches the most common class of bug (settings saved but cache not cleared).
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels