ホーム > Laravel > Basic Usage of Inertia.js
Laravel

Basic Usage of Inertia.js

Thank you for your continued support.
This article contains advertisements that help fund our operations.

A summary of the basic usage of Inertia.js in Laravel development.

Introduction

This is a comprehensive guide that serves as a reference for "how to write" in various situations.

The goal is to enable even first-time Laravel users to create pages step by step.

  1. Laravel 11
  2. Breeze with Inertia.js React selected

What is Laravel Breeze? A Summary of its Setup and Features

In this article, we will create a list page for the posts table and add a new creation feature.

Creating the Database

Creating the posts Table

Prepare two simple columns: title and content.

php artisan make:migration create_posts_table

Running the command generates database/migrations/2024_11_26_060317_create_posts_table.php. Open this file.

Editing the Migration File

Modify the file as follows:

    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title'); // Added
            $table->string('content'); // Added
            $table->timestamps();
        });
    }

Applying Database Changes via Command

php artisan migrate

If the posts table is successfully created, you are all set.

Creating the Post Model

Finally, create a Post model using a command:

php artisan make:model Post

If app/Models/Post.php is created, it’s ready to go.

Routing

Writing routes is no different from usual.

For this example, the list page will be accessible by everyone, while the new creation page will be restricted to authenticated users.

routes/web.php

Route::get('/posts',[PostController::class, 'index'])->name('post.index'); // List page

Route::middleware('auth')->group(function () {
    // ...
    Route::get('/post/create',[PostController::class, 'create'])->name('post.create'); // New creation page
    Route::post('/post',[PostController::class, 'store'])->name('post.store'); // Create new post
});

Basic Routing in Laravel

Controller

Creating the Controller

First, create a controller using a command:

php artisan make:controller PostController

This creates app/Http/Controllers/PostController.php. Open the file.

Editing the Controller

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Inertia\Inertia;

use Illuminate\Http\RedirectResponse;
use Inertia\Response;
use App\Models\Post;

class PostController extends Controller
{
    // List page
    public function index(): Response
    {
        $posts = Post::orderBy('id','desc')->get();
        return Inertia::render('Post/Index',compact('posts'));
    }

    // New creation page
    public function create(): Response
    {
        return Inertia::render('Post/Create');
    }

    // Create new post
    public function store(Request $request): RedirectResponse
    {
        $post = new Post;
        $post->title = $request->title;
        $post->content = $request->content;
        $post->save();
        return redirect()->route('post.index');
    }
}

Display

List Page

Display in the Browser

Access http://localhost/posts in your browser.

Initially, you might encounter an error.

Create Display File

Create resources/js/Pages/Post/Index.js to build a simple list page.

The path written in the return of the controller is relative to resources/js/Pages/.

Editing resources/js/Pages/Post/Index.js

import { Head, Link } from "@inertiajs/react"

export default function Index({ posts }) {
  const title = "Post List"
  return (
    <>
      <Head title={title} />

      <div className="w-4/5 mx-auto py-12">
        <h1>{title}</h1>
        <table className="table-auto">
          <thead>
            <tr>
              <th>Title</th>
              <th>Content</th>
            </tr>
          </thead>
          <tbody>
            {posts.map(post => {
              return (
                <tr>
                  <td>{post.title}</td>
                  <td>{post.content}</td>
                </tr>
              )
            })}
          </tbody>
        </table>
      </div>
    </>
  )
}

Using Variables

Variables sent from the controller can be used as follows:

export default function Index({ posts }) {

Here, posts is the variable you want to use. Simply include it in the props to use it.

For multiple variables:

export default function Index({ posts, hoge }) {

Just list them in the props.

New Creation Page

Similarly, create a new creation page.

Display in the Browser

Log in to view the page. Then access http://localhost/post/create in your browser.

Create Display File

Create resources/js/Pages/Post/Create.js to build the page.

Editing the Display File

import { Head, Link, useForm } from "@inertiajs/react"

export default function Edit() {
  const form = useForm({
    title: "",
    content: "",
  })

  const createPost = e => {
    e.preventDefault()
    form.post(route("post.store"), {
      preserveScroll: true,
      onSuccess: () => reset(),
      onError: errors => {
        // Handle errors here
      },
    })
  }

  const title = "Create New Post"
  return (
    <>
      <Head title={title} />

      <div className="w-4/5 mx-auto py-12">
        <h1>{title}</h1>
        <form onSubmit={createPost}>
          <div>
            <div>
              <input
                value={form.data.title}
                onChange={e => form.setData("title", e.target.value)}
                placeholder="Title"
              />
            </div>
            <div>
              <textarea
                value={form.data.content}
                onChange={e => form.setData("content", e.target.value)}
                placeholder="Content"
              ></textarea>
            </div>
            <button>Submit</button>
          </div>
        </form>
      </div>
    </>
  )
}

Managing Variables to Submit with useForm

import { Head, Link, useForm } from "@inertiajs/react"
const form = useForm({
  title: "",
  content: "",
})

Since the variables to submit are title and content, it is defined this way.

Using title and content in Display

To display them, use form.data.title.

For <input/> and <textarea></textarea>:

<input
  value={form.data.title}
  onChange={e => form.setData("title", e.target.value)}
  placeholder="Title"
/>

Submit Handling

When the <button> is clicked, the form is submitted:

<form onSubmit={createPost}>

This triggers the following function:

const createPost = e => {
  e.preventDefault() // Prevent default form submission
  form.post(route("post.store"), {
    preserveScroll: true,
    onSuccess: () => reset(), // Reset the form
    onError: errors => {
      // Handle errors here
    },
  })
}

form.post allows you to POST data such as title and content that were defined earlier.

route("post.store") corresponds to the part defined in routes/web.php as name('post.store'), which contains the endpoint (URL).

const createPost = e => {
  e.preventDefault() // Prevent default form submission
  // Omitted for brevity
}

This part is essential. Without it, the default form submission will proceed, conflicting with the approach of handling the form via this function.

In the browser, enter the title and content, click the submit button, and if the data is added to the database, it’s working correctly.

Conclusion

This concludes the summary of the basic usage of Inertia.js.

Indeed, it seems that writing frontend code with Laravel has become much more straightforward.

For small-scale services that don’t require separate frontend and backend development, this approach can be highly effective.

If you’re looking for development and operation of a small service with a predetermined design, feel free to reach out!

I hope this is helpful to someone.

Please Provide Feedback
We would appreciate your feedback on this article. Feel free to leave a comment on any relevant YouTube video or reach out through the contact form. Thank you!