Next.jsとLaravel 12のディレクトリを連結させる
やりたいこと
バックエンドとフロントエンドを別々のディレクトリで管理し、連携させる形にしたい。
一つのアプリにまとめず、以下の構成で運用する。
root/
├ backend/
└ frontend/
手順
まずは別々にフロントとバックエンドを環境構築する
Ftontend(Next.js Typescript)
今回はレイアウトの共有が楽なので、Next.jsを採用しました。
Nextの環境を作る
オプション 内容
--typescript TypeScriptで作成
--app App Router(app/ ディレクトリ)使用
--eslint Lintツール導入(任意)
--tailwind Tailwind CSS導入(任意)
--src-dir src/ ディレクトリ構成にする
--import-alias インポートエイリアス設定
上記のオプションで設定したい時は下記のコードにまとめることが可能です。
npx create-next-app@latest frontend --typescript --app --eslint --tailwind --src-dir --import-alias "@/*"
Would you like to use Turbopack for next dev? › No / Yes
上記の質問が出る場合は、Turbopack という開発用ビルドツールと使うかどうかを聞かれているようなので、Noを選択します(青文字の方が選択中)。
cd frontend
npm run dev
page.tsxを設定させておく
一旦連結しているかどうかを把握するためにsrc/app/page.tsxに下記を追加します。
'use client'
import { useEffect, useState } from 'react'
export default function Home() {
const [posts, setPosts] = useState([])
const [error, setError] = useState<string | null>(null)
useEffect(() => {
fetch('http://localhost/api/posts')
.then(res => {
if (!res.ok) {
throw new Error(`HTTPエラー: ${res.status}`)
}
return res.json()
})
.then(data => {
console.log('取得データ:', data)
setPosts(data)
})
.catch(err => {
console.error('Fetch error:', err)
setError(err.message)
})
}, [])
return (
<div>
<h1>Posts</h1>
{error && (
<p style={{ color: 'red' }}>
データ取得エラー: {error}
</p>
)}
{posts.length === 0 && !error && (
<p>読み込み中...</p>
)}
{posts.map((post: any) => (
<div key={post.id}>{post.title}</div>
))}
</div>
)
}
これでFrontエンドの表示で連結ができたか確認するための用意ができました。
BackendでLaravel12を用意する
なぜ12と強調するのかというと、Laravel12ではデフォルトではroute/app.phpがないからです。
Laravelで用意するファイルは下記の通り。
ProgreSQLを使用する場合
MySQLでない場合は下記コマンドだと早い。
curl -s "https://laravel.build/backend?with=pgsql" | bash
sail artisan migrateでテーブルを作ります。
route/api.phpを作る
route/api.phpを追加します。
参考にしたのは下記の記事。
コマンドなしでapi.phpを作ってもOK。
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
Route::get('/posts', [PostController::class, 'index']);
bootstrap/app.phpに追加
作った後はbootstrap/app.phpにコードを追加。
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware): void {
$middleware->prepend(\Illuminate\Http\Middleware\HandleCors::class);
})
->withExceptions(function (Exceptions $exceptions): void {
//
})->create();
デフォルトと違うのは、下記の通り
①api: DIR.'/../routes/api.php',
②->withMiddleware(function (Middleware $middleware): void {
$middleware->prepend(\Illuminate\Http\Middleware\HandleCors::class);
})
これ書かないと、apiを見に行ってくれません。
app/Http/Controllers/PostController.phpを作る
一旦PostControllerを作成。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index()
{
return response()->json([
['id' => 1, 'title' => 'テスト投稿'],
['id' => 2, 'title' => 'こんにちは Laravel']
]);
}
}
これでhttp://localhost/api/postsを見に行くと...

jsonが見えてAPIが通っているのがわかります。
ここで404になる時は、api.phpの記述が間違っているか、app.phpが間違っているかです。多分。

コントローラーに記載した内容を表示できました。
Discussion