Spring Boot bài 08: Fragment, layout và tài nguyên CSS trong Spring Boot
- 18-10-2026
- Toanngo92
- 0 Comments
Giáo trình Spring Boot MVC và REST API · Chương 4/12: Tổ chức giao diện Thymeleaf · Bài 08/28 · Biên soạn tháng 10/2026.
Mục lục
Mục tiêu bài học
Tách phần giao diện dùng chung, tạo URL tài nguyên đúng và xây layout gọn để các trang nhất quán.
Tránh sao chép phần đầu trang cho mọi template
Danh sách, chi tiết và biểu mẫu đều cần charset, viewport, tiêu đề, CSS và thanh điều hướng. Nếu chép nguyên các phần đó vào từng tệp, một lần đổi menu sẽ phải sửa nhiều nơi và dễ bỏ sót. Thymeleaf fragment cho phép đặt phần dùng chung vào một tệp rồi tham chiếu từ các trang.
Mã mẫu dùng templates/fragments/layout.html với fragment head(title) và nav. Đây là cơ chế fragment có sẵn của Thymeleaf, không cần cài thêm layout dialect. Khi mới học, giữ ít thành phần dùng chung sẽ dễ hiểu hơn một hệ thống layout nhiều tầng.
<!-- templates/fragments/layout.html: phần khai báo fragment -->
<head th:fragment="head(title)">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title th:text="${title}">HVC Academy</title>
<link rel="stylesheet" th:href="@{/css/app.css}">
</head>
<!-- Trong một trang dùng fragment -->
<head th:replace="~{fragments/layout :: head('Danh sách khóa học')}"></head>
<nav th:replace="~{fragments/layout :: nav}"></nav>
th:replace khác th:insert
th:replace thay chính phần tử hiện tại bằng fragment; th:insert chèn fragment vào bên trong phần tử. Dùng nhầm có thể tạo head lồng head hoặc nav lồng nav không cần thiết. Sau khi render, hãy xem DOM thực tế để kiểm tra cấu trúc, không chỉ nhìn tệp nguồn.
Tham số title giúp mỗi trang có tiêu đề riêng dù dùng chung phần head. Những phần có nội dung đặc thù vẫn đặt trong template của trang. Không biến mọi đoạn HTML ngắn thành fragment nếu việc đó làm khó tìm nội dung hơn.
Đặt CSS ở đúng nơi
Tệp src/main/resources/static/css/app.css được phục vụ qua URL /css/app.css. Không có /static trong URL công khai; static là tên thư mục quy ước trong nguồn. Template dùng @{/css/app.css} để xây URL phù hợp với context path của ứng dụng.
SecurityConfig cho phép /css/** truy cập công khai, nên trang đăng nhập hoặc người chưa đăng nhập cũng tải được giao diện. Nếu HTML hiện nhưng CSS 302 về /login, hãy kiểm tra Security và Network trước khi kết luận file CSS không tồn tại. Không bỏ bảo mật toàn ứng dụng để chữa một đường dẫn tài nguyên.
Menu và thao tác thay đổi trạng thái
Liên kết xem trang có thể dùng GET. Đăng xuất trong mẫu là form POST với th:action, vì nó làm thay đổi phiên đăng nhập và cần CSRF token. Không chuyển logout thành một đường dẫn GET chỉ để menu dễ bố trí. CSS có thể làm form nhỏ gọn mà vẫn giữ đúng phương thức HTTP.
Layout cũng cần dùng được trên màn hình nhỏ: viewport đúng, chiều rộng nội dung có giới hạn, input không tràn và bảng có cách xử lý khi nhiều cột. Bản mẫu dùng CSS tối giản để người học nhìn rõ cấu trúc; bạn có thể thay giao diện sau khi luồng dữ liệu ổn định. Luôn kiểm tra ít nhất trang danh sách, form và trang lỗi sau khi đổi fragment dùng chung.
Lỗi thường gặp và lưu ý
- Không đặt CSS trong templates rồi chờ Spring phục vụ nó như tài nguyên tĩnh.
- Cẩn thận cấu trúc HTML lồng sai khi dùng th:insert hoặc th:replace.
Ghi nhớ
Fragment giúp giao diện nhất quán; tài nguyên tĩnh có đường dẫn công khai rõ ràng và quy tắc Security riêng.

