frontend Öne Çıkan
3200 yıldız

Inertia.js Laravel Adapter

Geliştirici: Jonathan Reinink & Inertia.js

API oluşturmadan Vue, React veya Svelte bileşenlerini klasik Laravel controller ve view yapısıyla SPA olarak çalıştırmayı sağlayan adaptör.

Kurulum

Composer
composer require inertiajs/inertia-laravel

Dokümantasyon & Kullanım

Markdown

Inertia.js Laravel Adaptörü

Inertia.js, istemci tarafında modern SPA (Single Page Application) framework'lerinin (Vue.js, React veya Svelte) gücünü kullanırken; arka planda klasik sunucu taraflı Laravel controller'ları, routing, ORM ve middleware yeteneklerinden ödün vermeden çalışmanızı sağlayan "Monolith SPA" köprüsüdür. Ayrı bir REST veya GraphQL API yazma ihtiyacını tamamen ortadan kaldırır.

Neden Tercih Edilmeli?

  • API Yazma Zorunluluğu Yok: OAuth, JWT, karmaşık API endpoint'leri ve durum yönetimi (state management) ile uğraşmadan doğrudan Controller'dan prop dönersiniz.
  • Klasik Laravel Routing: Tüm rotalar routes/web.php içinde tanımlanır; middleware, yetkilendirme ve yönlendirmeler Laravel tarafında kalır.
  • Gerçek SPA Hızı ve Akıcılığı: Sayfa geçişlerinde tarayıcı tam yenilenmez, yalnızca JSON veri aktarılarak bileşen anında yeniden render edilir.
  • Kısmi Yenileme (Partial Reloads): Sadece değişen prop'ları yükleyerek ağ trafiğini optimize eder.
  • Form Yardımcıları & Doğrulama: Form durumları, yükleniyor göstergeleri ve Laravel Form Request hata mesajları otomatik senkronize edilir.

Kurulum

Composer ile Laravel adaptörünü yükleyin:

composer require inertiajs/inertia-laravel

Kök Blade şablonunu (resources/views/app.blade.php) oluşturun:

<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Laravel & Inertia</title>
    @vite(['resources/js/app.js'])
    @inertiaHead
</head>
<body class="bg-dark text-white">
    @inertia
</body>
</html>

Inertia middleware'ini yayınlayın:

php artisan inertia:middleware

bootstrap/app.php içinde middleware'i web grubuna ekleyin:

use App\Http\Middleware\HandleInertiaRequests;

->withMiddleware(function (Middleware $middleware) {
    $middleware->web(append: [
        HandleInertiaRequests::class,
    ]);
})

Temel Kullanım

Controller Tarafı (PHP)

Klasik view() yerine Inertia::render() kullanılır:

namespace App\Http\Controllers;

use App\Models\User;
use Inertia\Inertia;
use Inertia\Response;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function index(Request $request): Response
    {
        return Inertia::render('Users/Index', [
            'users' => User::query()
                ->when($request->search, fn ($q, $s) => $q->where('name', 'like', "%{$s}%"))
                ->paginate(10)
                ->withQueryString(),
            'filters' => $request->only(['search']),
        ]);
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email|unique:users',
        ]);

        User::create($validated);

        return redirect()->route('users.index')->with('success', 'Kullanıcı oluşturuldu.');
    }
}

Frontend Bileşeni (Vue.js 3 Örneği)

resources/js/Pages/Users/Index.vue:

<template>
    <div class="container mx-auto py-8">
        <div class="flex justify-between items-center mb-6">
            <h1 class="text-2xl font-bold">Kullanıcı Listesi</h1>
            <Link href="/users/create" class="btn btn-primary">Yeni Ekle</Link>
        </div>

        <input 
            v-model="search" 
            placeholder="Kullanıcı ara..." 
            class="input mb-4"
        />

        <div class="bg-gray-900 rounded-lg overflow-hidden">
            <table class="w-full text-left">
                <thead>
                    <tr class="border-b border-gray-800">
                        <th class="p-4">İsim</th>
                        <th class="p-4">E-posta</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="user in users.data" :key="user.id" class="border-b border-gray-800">
                        <td class="p-4">{{ user.name }}</td>
                        <td class="p-4">{{ user.email }}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</template>

<script setup>
import { ref, watch } from 'vue';
import { router, Link } from '@inertiajs/vue3';

const props = defineProps({
    users: Object,
    filters: Object,
});

const search = ref(props.filters.search || '');

watch(search, (value) => {
    router.get('/users', { search: value }, {
        preserveState: true,
        replace: true,
    });
});
</script>