📥 Importing Customer Data into Laravel Filament from a CSV File (Beginner’s Guide)

When building a dashboard using Laravel Filament, I found myself needing to import customer data from a CSV file instead of manually adding it through a form.

Since most real-world projects start with existing data, this seemed like a great learning opportunity.

In this blog post, I’ll walk through:

  • How to import a CSV file into Laravel using a factory
  • How I integrated it with a Customer model
  • Troubleshooting errors I faced (and solved)
  • Why this is useful when working with Filament

Let’s go!


đź§± Step 1: Setting Up the Customer Model, Migration, Factory

First, I created everything I needed with Artisan:

php artisan make:model Customer -mfs

This created:

  • A model: app/Models/Customer.php
  • A migration for the customers table
  • A factory for generating fake customer data
  • A seeder for inserting the data

🛠️ My Migration Looked Like This:

Schema::create('customers', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email');
    $table->string('phone');
    $table->timestamps();
});

Then I ran the migration:

php artisan migrate

đź“„ Step 2: Creating the CSV File

I created a file named customers.csv and placed it in storage/app/ with the following content:

name,email,phone
Kimberly Martin,kcurtismartin@gmail.com,(205) 463-2165
Derek Black,derekb@example.com,(210) 555-9090

🌱 Step 3: Writing a Seeder to Import CSV

In the CustomerSeeder.php, I wrote the logic to read this CSV file and insert data using a factory:

use App\Models\Customer;
use Illuminate\Database\Seeder;

class CustomerSeeder extends Seeder
{
    public function run(): void
    {
        $path = storage_path('app/customers.csv');
        $rows = array_map('str_getcsv', file($path));
        
        // Clean header (remove BOM if present)
        $header = array_map(function ($h) {
            return trim(str_replace("\xEF\xBB\xBF", '', $h));
        }, array_shift($rows));

        foreach ($rows as $row) {
            if (count($row) !== count($header)) {
                continue;
            }

            $data = array_combine($header, array_map('trim', $row));

            Customer::factory()->create([
                'name' => $data['name'],
                'email' => $data['email'],
                'phone' => $data['phone'],
            ]);
        }
    }
}

❌ The First Error I Faced

I got this error:

SQLSTATE[HY000]: General error: 1 table customers has no column named name

đź§Ş Diagnosis

This meant that the customers table didn’t actually have a name column — even though I thought it did!

âś… Fix

I had either forgotten to migrate or didn’t include name in the migration. I updated the migration and ran:

php artisan migrate:fresh --seed

This dropped and re-created the tables and ran the seeders — now everything worked!


âť— Last Issue: Fields Were Empty in Database

Even though seeding succeeded, the phone, created_at, and updated_at fields were blank.

đź§Ş Diagnosis

The fields were being overridden or not passed correctly. I double-checked with dd($data); and saw that the values were fine.

The issue turned out to be:

  • My model might not have had $fillable defined
  • The factory might’ve been overriding values

âś… Final Fixes

In Customer.php, I added:

protected $fillable = ['name', 'email', 'phone'];

And I made sure the factory wasn’t overriding values when data was passed into create().


🎉 Final Result

I now have:

  • A fully working Customer model
  • CSV data imported into the database
  • Data displayed using a Filament resource table (php artisan make:filament-resource Customer --generate)
  • Optionally: I can add dashboard widgets and charts later

đź§  Why This is Useful in Filament Projects

âś… Pros

  • Quickly seed real-world data from a spreadsheet (CSV)
  • Clean integration with Laravel factories and seeders
  • No need to enter records one-by-one
  • Easily show this data in Filament’s searchable tables
  • Great for prototyping admin dashboards

❌ Cons

  • Requires careful CSV formatting (no empty rows or BOM issues)
  • Needs basic Laravel knowledge (models, seeders, migrations)
  • Not built-in to Filament (but easy to add manually)

🔚 What’s Next?

Now that I can import CSV data into my Laravel app and display it with Filament:

  • I plan to explore Filament Widgets to show stats and charts
  • Then I’ll move into authentication (login, logout)
  • After that, I’ll return to learning Blade and Tailwind CSS for more control over the frontend

📝 Final Thoughts

Importing a CSV file into Laravel and displaying it with Filament might sound complicated at first, but once you understand how Laravel’s factory, model, and seeder system works — it becomes quite easy and powerful.

If you’re starting with existing data and want a clean admin interface, Filament is the perfect tool to help you move fast and learn more.