Autosave plugin screenshot
Dark mode ready
Multilingual support
Supports v5.x

Autosave

Community

Save Filament forms automatically, with a live status indicator, undo support, and local drafts.

Tags: Forms Spatie Integration
Supported versions:
5.x 4.x
lenorix avatar Author: lenorix

Package health

Beta

Automated checks of this plugin's Composer package

95 / 100
Security 96
Maintenance 90
Ecosystem 100
15 checks
  • Passed: GitHub Actions pinned to SHA
  • Skipped: GitLab CI includes pinned to SHA
  • Passed: Open security advisories
  • Passed: Dependabot PR responsiveness — No open Dependabot PRs.
  • Skipped: Renovate MR responsiveness
  • Warning: Dependabot or Renovate configured — Updater does not cover the JavaScript ecosystem, which has a committed lockfile.
  • Passed: Dependency update cooldown configured
  • Passed: Provides a security policy
  • Passed: Abandoned or archived — No consulted source marks the package abandoned (packagist, github).
  • Passed: Commit and release recency — Active: last commit 0 days ago; last release 1 days ago.
  • Passed: composer.lock not committed by library composer.lock is absent from the released dist archive.
  • Warning: Dist archive is lean
  • Passed: Current Laravel version supported — Package dependencies resolve together with current Laravel 13.0.
  • Passed: Current PHP version supported — Constraint ~8.4.0 || ~8.5.0 supports current PHP 8.5.
  • Skipped: Current Symfony version supported
Third-party plugin. This is built by the community, not the Filament team. Filament does not review, endorse, or vet the security of plugins outside the filament/ namespace. Review the source and install at your own risk. Found malware or an unresolved security issue the author won't address? Report it .
Powered by Plumb Last scanned 7 hours ago

Documentation

Latest Version on Packagist Total Downloads Tests License Plumb score

Filament Autosave saves form changes after the user pauses typing. It writes only the fields that changed, keeps untouched fields up to date when other editors save, and offers one-step Undo.

It works with Edit and Create pages, relation managers, actions, modals, table forms, and standalone Livewire forms. Optional integrations support Spatie Media Library (filament/spatie-laravel-media-library-plugin) and translatable Edit pages (lara-zeus/spatie-translatable).

#Requirements

  • PHP 8.4 or 8.5
  • Laravel 12 or 13
  • Filament 4.13+ or 5
  • Livewire 3 with Filament 4, or Livewire 4 with Filament 5

#Installation

composer require lenorix/filament-autosave

Register the plugin in your panel provider:

use Lenorix\FilamentAutosave\AutosavePlugin;

public function panel(Panel $panel): Panel
{
    return $panel->plugin(AutosavePlugin::make());
}

Edit pages now autosave with the default settings. Publish the config, translations, or views only when you need to change them. No Node build step is required:

php artisan vendor:publish --tag="filament-autosave-config"
php artisan vendor:publish --tag="filament-autosave-translations"
php artisan vendor:publish --tag="filament-autosave-views"

#Add autosave to a form

#Edit pages

use Filament\Resources\Pages\EditRecord;
use Lenorix\FilamentAutosave\HasAutosave;

class EditArticle extends EditRecord
{
    use HasAutosave;

    protected static string $resource = ArticleResource::class;
}

Modified fields are saved after 750 ms without input. The indicator and Undo action are added automatically.

#Create pages

Use HasAutosaveForCreate to keep an unfinished form as a draft:

use Filament\Resources\Pages\CreateRecord;
use Lenorix\FilamentAutosave\HasAutosaveForCreate;

class CreateArticle extends CreateRecord
{
    use HasAutosaveForCreate;

    protected static string $resource = ArticleResource::class;
}

Users can restore or discard drafts. Drafts survive validation errors and are removed after the record is created. They do not create records or permanently store files and media until the form is submitted.

For a custom page that stores its form in $data, call $this->clearAutosaveDraft() after a successful save.

#Relation managers

Add HasAutosaveForRelationManager to autosave create and edit modals:

use Filament\Resources\RelationManagers\RelationManager;
use Lenorix\FilamentAutosave\HasAutosaveForRelationManager;

class CommentsRelationManager extends RelationManager
{
    use HasAutosaveForRelationManager;

    protected static string $relationship = 'comments';
}

Clear a creation draft after the action creates its record:

CreateAction::make()
    ->after(fn (CommentsRelationManager $livewire) => $livewire->clearAutosaveDraft());

#Actions, modals, table forms, and Livewire components

Use HasAutosaveForForm for forms outside resource pages:

use Livewire\Component;
use Lenorix\FilamentAutosave\HasAutosaveForForm;

class EditCommentForm extends Component
{
    use HasAutosaveForForm;

    public ?array $data = [];
    public string|int|null $recordId = null;

    public function mount(): void
    {
        $this->mountHasAutosaveForForm();
    }

    protected function getAutosaveFormContext(): string
    {
        return 'comment:'.$this->recordId;
    }
}

The context must be stable and unique for the owner, record, or action. This keeps drafts and Undo snapshots separate. Enable require_form_context to reject forms without an explicit context.

Include the indicator in the component view:

@include('filament-autosave::autosave-indicator', ['mode' => 'form'])

For action forms whose state lives under mountedActions.*.data, override resolveAutosaveForm() and getAutosaveStatePath() to return the active schema and state path.

#What gets saved

Autosave writes changed, valid form data and leaves the rest of the record alone.

  • Regular fields, JSON and relationship repeaters, uploads, media, and RichEditor are supported.
  • Password fields, dehydrated(false), and fields listed in except are never saved.
  • With dirty_only enabled (the default), each cycle writes only fields that changed.
  • Invalid fields are skipped without clearing their stored value; valid sibling fields can still be saved.
  • Groups, builders, and other single-column fields are saved only when all child inputs are valid.
  • Filament validation, hooks, events, and page authorization still run.

Add autosave-only rules or a post-save hook when needed:

protected function getAutosaveValidationRules(): array
{
    return ['slug' => ['required', 'string', 'max:120']];
}

protected function afterAutosave(object $record): void
{
    // Run work after a successful Edit-page autosave.
}

#Keep editors in sync

Different fields can be edited at the same time without overwriting each other. Changes to the same field use last-write-wins unless text merging is enabled.

#Refresh and polling

refresh_unchanged_fields refreshes untouched model columns in the save response. It is enabled by default and does not replace values the current user is editing.

Set poll_interval to check for remote changes in the background. It defaults to 5 seconds; 0 disables polling. Polling requires refresh_unchanged_fields and is available on Edit pages and record-backed forms.

Polling updates untouched columns, repeaters, uploads, and media. Locally edited fields are marked stale instead of being overwritten. Nested relationship fields are fingerprinted up to poll_relationship_depth (3 by default), so deep child changes no longer require $touches on the parent. Set the depth to 0 for direct relationships only. Timestamp-free relations hash their rows up to poll_relationship_max_rows (500 by default); larger relations use a cheap key/count check, so timestamp columns are recommended for large collections. Set poll_relationships to false or call pollRelationships(false) for column-only polling.

#Merge text fields

Configure top-level TextInput, Textarea, MarkdownEditor, or RichEditor fields to merge non-overlapping edits:

AutosavePlugin::make()
    ->mergeFields(['title', 'body'])
    ->pollInterval(10_000);

Overlapping changes still use last-write-wins. The previous version can be restored from the conflict notice, and Undo restores the state from before the merge.

#Undo

Undo is available for 5 seconds after a save. Snapshots are kept for 90 minutes by default.

  • Restores saved attributes, pivot data, and supported relationships.
  • Stops when the fields being restored changed remotely, so Undo does not overwrite newer work.
  • Relation snapshots are limited by relationship_undo_depth (8 by default).
  • Files and media are excluded unless a reversible external_undo_adapters adapter is configured.

#Uploads and media

Native FileUpload fields support uploads, removals, reordering, and size/MIME validation. Invalid uploads skip only their field. Hidden, disabled, excluded, and storeFiles(false) fields are skipped.

Spatie Media Library support requires:

composer require filament/spatie-laravel-media-library-plugin

Media in relationship repeaters is attached after the child record is created. In JSON repeaters, use a unique media collection per row, for example:

Repeater::make('settings')->schema([
    Hidden::make('uuid')->default(fn (): string => (string) Str::uuid()),
    SpatieMediaLibraryFileUpload::make('images')
        ->multiple()
        ->collection(fn (Get $get): string => 'row_'.$get('uuid')),
]),

Edit and Create page autosaves use database transactions. Generic forms use the host transaction when one is available. Failed saves remove newly stored files and media. Schedule cleanup for files left by interrupted requests:

$schedule->command('filament-autosave:prune-uploads')->everyThirtyMinutes();

#Explicit saves

Use flushAutosave() when a button, action, or modal must save immediately:

$written = $this->flushAutosave(); // bool

It runs the same dirty-only save, refresh, and Undo flow synchronously. Validation and persistence exceptions are thrown to the caller. The background autosave() method reports failures through the indicator instead.

#Configuration

Plugin settings override the published config, and page settings override the plugin:

AutosavePlugin::make()
    ->debounce(2_000)
    ->pollInterval(10_000)
    ->pollRelationships(false)
    ->mergeFields(['title'])
    ->except(['internal_notes'])
    ->showTimestamp(false)
    ->indicatorPosition('after');

Publish the config to change options without a plugin method, such as dirty_only, refresh_unchanged_fields, poll_interval, poll_relationships, relationship_undo_depth, and require_form_context.

#Translations and indicator

Publish translations with filament-autosave-translations. English is included by default.

The indicator shows save status, timestamps, pending or stale fields, validation messages, and Undo. It is added automatically on resource pages. Generic forms include it with:

@include('filament-autosave::autosave-indicator', ['mode' => 'form'])

Package lifecycle events are available under Lenorix\FilamentAutosave\Events when the application needs to react to saves, failures, synchronization, or Undo.

#License

The Unlicense

The author

lenorix avatar Author: lenorix

Drawing The Future Together. We create software for people.

Plugins
1