Giới thiệu tổng quan
Khi xây dựng một ứng dụng web hiện đại, việc kết hợp Laravel làm backend API và Next.js + React làm frontend đang trở thành xu hướng phổ biến. Bài viết này sẽ hướng dẫn chi tiết cách kết nối API Laravel vào dự án Next.js, đồng thời sử dụng React Query để quản lý dữ liệu một cách hiệu quả, giảm thiểu số lần gọi API và cải thiện trải nghiệm người dùng.
1. Chuẩn bị API Laravel
1.1 Cấu hình CORS
Để Next.js có thể truy cập các endpoint của Laravel, bạn cần bật CORS trong file app/Http/Middleware/TrustProxies.php hoặc sử dụng package fruitcake/laravel-cors. Dưới đây là cấu hình nhanh trong config/cors.php:
<?php
return [
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'], // hoặc giới hạn domain Next.js
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];
1.2 Định nghĩa route và controller
Giả sử chúng ta muốn trả về danh sách bài viết. Tạo route trong routes/api.php và controller PostController:
Route::get('/posts', [App\Http\Controllers\PostController::class, 'index']);
Controller:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index(Request $request)
{
// Sử dụng pagination để giảm tải dữ liệu
$posts = Post::orderBy('created_at', 'desc')->paginate(10);
return response()->json($posts);
}
}
2. Tích hợp vào Next.js
2.1 Cài đặt React Query
Trong dự án Next.js, chạy lệnh sau để cài đặt:
npm install @tanstack/react-query axios
2.2 Tạo client API
Sử dụng axios để cấu hình baseURL trỏ tới server Laravel:
import axios from 'axios';
export const apiClient = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000/api',
timeout: 5000,
});
2.3 Sử dụng React Query trong trang
Trong file pages/posts.js, chúng ta sẽ fetch dữ liệu bằng useQuery và hiển thị danh sách:
import { useQuery } from '@tanstack/react-query';
import { apiClient } from '../utils/apiClient';
function fetchPosts() {
return apiClient.get('/posts').then(res => res.data);
}
export default function PostsPage() {
const { data, error, isLoading } = useQuery(['posts'], fetchPosts, {
staleTime: 1000 * 60 * 5, // 5 phút
keepPreviousData: true,
});
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<h1>Danh sách bài viết</h1>
<ul>
{data.data.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}
2.4 Tối ưu SSR với getServerSideProps
Đối với SEO và tốc độ tải trang, bạn có thể prefetch dữ liệu ở server bằng getServerSideProps và hydrate React Query:
import { dehydrate, QueryClient } from '@tanstack/react-query';
import { fetchPosts } from '../services/postService';
export async function getServerSideProps() {
const queryClient = new QueryClient();
await queryClient.prefetchQuery(['posts'], fetchPosts);
return {
props: {
dehydratedState: dehydrate(queryClient),
},
};
}
3. Những lưu ý quan trọng
- Bảo mật token: Khi API yêu cầu xác thực, lưu token trong
httpOnly cookievà truyền quaaxiosvớiwithCredentials: true. - Pagination: Luôn sử dụng pagination ở backend để tránh trả về quá nhiều bản ghi, đồng thời kết hợp
fetchNextPagecủa React Query để tải thêm khi người dùng cuộn. - Cache invalidation: Khi thực hiện thao tác tạo, sửa, xóa, gọi
queryClient.invalidateQueries(['posts'])để làm mới dữ liệu. - Error handling: Sử dụng
onErrortronguseQueryđể hiển thị thông báo người dùng và ghi log phía server.
Kết luận
Việc kết hợp Laravel API với Next.js và React Query không chỉ giúp tách biệt rõ ràng frontend và backend mà còn tối ưu hiệu năng tải trang và trải nghiệm người dùng. Để nắm vững quy trình từ cấu hình CORS, xây dựng endpoint, tới việc prefetch dữ liệu SSR, bạn có thể Tham khảo khóa học "Xây dựng ứng dụng kết hợp Laravel - ReactJS - NextJS" tại đây.








