Build a Blog Platform with Laravel and Livewire

Build a Blog Platform with Laravel and Livewire

Build a Blog Platform with Laravel and Livewire

This project walks you through building a complete blog platform from scratch using Laravel 12 and Livewire 3. By the end you will have a production-ready application with a public-facing blog and a reactive admin panel.

Features

  • Post creation with rich-text editor (Trix)
  • Categories and tags with many-to-many relationships
  • Nested comments with moderation
  • Image uploads stored on Laravel Storage
  • Admin dashboard with Livewire data tables
  • Full-text search with Laravel Scout
  • RSS feed and sitemap generation

Step 1 — Project Setup

composer create-project laravel/laravel blog-platform
cd blog-platform
composer require livewire/livewire
php artisan livewire:install

Step 2 — Database Schema

php artisan make:model Post -mfsc
php artisan make:model Category -mfsc
php artisan make:model Tag -mfsc
php artisan make:model Comment -mfs
// Post migration
Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained()->cascadeOnDelete();
    $table->foreignId('category_id')->constrained();
    $table->string('title');
    $table->string('slug')->unique();
    $table->text('excerpt')->nullable();
    $table->longText('body');
    $table->string('cover_image')->nullable();
    $table->timestamp('published_at')->nullable();
    $table->timestamps();
});

Step 3 — Eloquent Relationships

// Post model
class Post extends Model
{
    use HasSlug, SoftDeletes;

    public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }

    public function tags(): BelongsToMany
    {
        return $this->belongsToMany(Tag::class);
    }

    public function comments(): HasMany
    {
        return $this->hasMany(Comment::class)->whereNull('parent_id');
    }

    public function scopePublished(Builder $query): void
    {
        $query->whereNotNull('published_at')
              ->where('published_at', '<=', now());
    }
}

Step 4 — Livewire Post Editor

php artisan make:livewire Admin/PostEditor
class PostEditor extends Component
{
    public ?Post $post = null;
    public string $title = '';
    public string $body = '';
    public ?int $categoryId = null;
    public array $selectedTags = [];

    #[Rule(['required', 'min:3'])]
    public string $titleInput = '';

    public function save(): void
    {
        $this->validate();

        $this->post = Post::updateOrCreate(
            ['id' => $this->post?->id],
            [
                'title'       => $this->title,
                'slug'        => Str::slug($this->title),
                'body'        => $this->body,
                'category_id' => $this->categoryId,
            ]
        );

        $this->post->tags()->sync($this->selectedTags);
        $this->dispatch('saved');
    }
}
All Comments