Build a Todo App with Laravel, React & Inertia.js: Zero API Headaches!
๐ก Why This Combo is Magic
Imagine building a LEGO castle:
- Laravel = Foundation plates (backend structure)
- React = Colorful bricks (UI components)
- Inertia.js = Instruction manual (seamless connection)
No glue, no duct tape โ everything snaps together perfectly! Today, weโll build a fully functional Todo app without writing a single API endpoint. Letโs dive in!
๐ ๏ธ Setup: Install the Power Trio
1. Create Laravel Project
laravel new inertia-todo
cd inertia-todo
2. Install Inertia + React
composer require inertiajs/inertia-laravel
npm install @inertiajs/react react react-dom
3. Configure Inertia
Update resources/views/app.blade.php:
<!DOCTYPE html>
<html>
<head>
@vite('resources/js/app.js')
</head>
<body>
<div id="app" data-page="{{ json_encode($page) }}"></div>
</body>
</html>
Create resources/js/app.js:
import { createInertiaApp } from '@inertiajs/react';
import { createRoot } from 'react-dom/client';
createInertiaApp({
resolve: name => require(`./Pages/${name}`),
setup({ el, App, props }) {
createRoot(el).render(<App {...props} />);
},
});
๐ฆ Step 1: Create Todo Model & Migration
Generate Model + Migration
php artisan make:model Todo -m
Edit migration file (database/migrations/..._create_todos_table.php):
public function up() {
Schema::create('todos', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->boolean('completed')->default(false);
$table->timestamps();
});
}
Run migration:
php artisan migrate
๐ Step 2: Build Laravel Controller
Create Controller
php artisan make:controller TodoController
Edit app/Http/Controllers/TodoController.php:
use App\Models\Todo;
use Inertia\Inertia;
use Illuminate\Http\Request;
class TodoController extends Controller {
// Show all todos
public function index() {
return Inertia::render('Todos/Index', [
'todos' => Todo::latest()->get()
]);
}
// Add new todo
public function store(Request $request) {
Todo::create($request->validate(['title' => 'required|min:3']));
return redirect()->back();
}
// Update completion status
public function update(Request $request, Todo $todo) {
$todo->update(['completed' => $request->completed]);
return redirect()->back();
}
// Delete todo
public function destroy(Todo $todo) {
$todo->delete();
return redirect()->back();
}
}
๐ Step 3: Define Routes
Edit routes/web.php:
use App\Http\Controllers\TodoController;
Route::get('/', [TodoController::class, 'index']);
Route::post('/todos', [TodoController::class, 'store']);
Route::put('/todos/{todo}', [TodoController::class, 'update']);
Route::delete('/todos/{todo}', [TodoController::class, 'destroy']);
โ๏ธ Step 4: Build React Components
1. Main Page (resources/js/Pages/Todos/Index.jsx)
import { Head, Link } from '@inertiajs/react';
import TodoForm from './Form';
import TodoList from './List';
export default function TodoIndex({ todos }) {
return (
<div className="max-w-2xl mx-auto p-8">
<Head title="Your Todo List" />
<h1 className="text-3xl font-bold mb-6">โจ Your Todo List</h1>
<TodoForm />
<TodoList todos={todos} />
</div>
);
}
2. Todo Form (resources/js/Pages/Todos/Form.jsx)
import { useForm } from '@inertiajs/react';
export default function TodoForm() {
const { data, setData, post, processing } = useForm({
title: ''
});
const submit = (e) => {
e.preventDefault();
post('/todos');
};
return (
<form onSubmit={submit} className="mb-8">
<input
type="text"
value={data.title}
onChange={e => setData('title', e.target.value)}
placeholder="Buy groceries..."
className="w-full p-3 border rounded"
disabled={processing}
/>
<button
type="submit"
className="mt-2 bg-blue-500 text-white p-2 rounded"
disabled={processing}
>
{processing ? 'Adding...' : 'Add Task'}
</button>
</form>
);
}
3. Todo List (resources/js/Pages/Todos/List.jsx)
import { Link } from '@inertiajs/react';
export default function TodoList({ todos }) {
return (
<div className="space-y-4">
{todos.map(todo => (
<div key={todo.id} className="flex items-center justify-between p-4 bg-white shadow rounded">
<div className="flex items-center">
<input
type="checkbox"
checked={todo.completed}
onChange={() => Inertia.put(`/todos/${todo.id}`, {
completed: !todo.completed
})}
className="mr-3 h-5 w-5"
/>
<span className={todo.completed ? 'line-through text-gray-500' : ''}>
{todo.title}
</span>
</div>
<button
onClick={() => Inertia.delete(`/todos/${todo.id}`)}
className="text-red-500 hover:text-red-700"
>
Delete
</button>
</div>
))}
</div>
);
}
๐ Launch Your App!
- Start backend:
php artisan serve - Start frontend:
npm run dev - Visit
http://localhost:8000
Behold! Your fully functional Todo app:
- โ Add tasks
- โ Mark as complete
- โ Delete items
- โก All updates happen without page reloads!
๐ How It Works: The Inertia Magic
User adds task:
- React form โ Laravel
store()method โ Database - No API layer!
- React form โ Laravel
User checks todo:
- Inertia sends PUT request โ Laravel
update()method - Database updated โ React UI instantly re-renders
- Inertia sends PUT request โ Laravel
User deletes item:
- Inertia.delete() โ Laravel
destroy() - Item vanishes from UI instantly
- Inertia.delete() โ Laravel
โจ Key Takeaways
- No API Boilerplate: Inertia lets Laravel controllers talk directly to React!
- Real-Time UI Updates: Pages update without reloads (SPA experience).
- Shared Validation: Use Laravel validation rules in React forms.
- Blazing Fast Dev: Build full-stack features in record time.
๐ก Pro Tip: Add Laravel Breeze for authentication:
composer require laravel/breeze --dev php artisan breeze:install react
๐ Your Next Challenge
Enhance your Todo app with:
- Due dates
- Priority levels
- Drag-and-drop sorting
Questions? Drop them below! ๐
Projects to explore next
Source-code projects from the KritiMyantra catalogue. Check each project's details before buying.
Flask Authentication System (Free Version) - Kritim Yantra
๐ Featuresโ Google & GitHub Authenticationโ User Registration & Loginโ Profile/Dashboard Accessโ Secure & Mi...
Flask Blog CMS with Admin Dashboard โ Python Source Code
A Flask-based blogging website with a built-in admin dashboard. Manage articles, images, categories, tags and featured p...
Laravel 12 + ReactJS Starter Kit: Add Multi-Language Support (Arabic, English, Spanish) with Blog CRUD
๐ Installation & Setup Download & Extract Get the ZIP from kritimyantra.com and extract it. Includes preconfigu...
Comments
No comments yet. Be the first to comment.
Sign in to join the discussion.