Đối với một nhà thiết kế đang hành nghề, một trang web portfolio thường nằm ở một vị thế lửng lơ khó xử. Nó cần phải trông thật sắc nét, tải tức thì và luôn được cập nhật mà không làm tiêu tốn quá nhiều giờ làm việc có tính phí. Hệ thống cũ của tôi chạy trên Webflow, một công cụ giúp thu hẹp khoảng cách giữa các trình xây dựng kéo-thả và kết quả chuyên nghiệp tốt hơn hầu hết các công cụ khác. Nhưng khi nhận được thông báo gia hạn với hóa đơn 300 bảng Anh hàng năm, tôi đã phải tự đặt ra một câu hỏi hóc búa: tôi đang trả tiền cho giá trị thực sự, hay chỉ là cho sự tiện lợi?

Tôi quyết định xây dựng lại mọi thứ từ đầu. Bộ công cụ (stack) mới là Astro và Sanity. Sau một thời gian trải nghiệm, đây chính xác là những gì đã hiệu quả, những gì không, và vị thế của chúng so với các công cụ tôi đã sử dụng trước đây.

Tại sao lại chọn Astro cho một portfolio?

Hầu hết các framework web hiện đại đều ưu tiên gửi JavaScript trước rồi mới tính đến các vấn đề khác. Astro đảo ngược giả định đó. Nó tạo ra các tệp HTML tĩnh thuần túy tại thời điểm build và chỉ gửi JavaScript đến trình duyệt khi một component cụ thể thực sự cần đến nó. Họ gọi đây là kiến trúc islands (islands architecture), nhưng kết quả thực tế thì đơn giản hơn: các trang portfolio của tôi gần như không tốn dung lượng.

Việc định tuyến (routing) dựa trên tệp tin, vì vậy việc tạo một trang mới dễ dàng như việc thả một tệp vào thư mục. Các component sử dụng cú pháp sẽ cảm thấy quen thuộc nếu bạn đã từng chạm qua React, Vue hoặc Svelte. Tôi không phải học một mô hình mới mỗi khi muốn thêm một bài nghiên cứu dự án (case study).

Tuy nhiên, tôi sẽ không dùng Astro để xây dựng một ứng dụng web phức tạp. Nếu bạn đang thiết lập xác thực (authentication), quản lý trạng thái toàn cục (global state), hoặc xử lý dữ liệu thời gian thực, bạn sẽ phải "vật lộn" với framework này. Nhưng đối với các trang marketing, blog và portfolio, nó hoạt động cực kỳ mượt mà. Các trang web có cảm giác nhanh vì chúng thực sự nhanh. Không có độ trễ hydration nào đang chờ để render một tiêu đề hay một đoạn văn.

Chuyển đổi từ WordPress sang Sanity

Trước khi xây dựng lại, phương án dự phòng của tôi luôn là WordPress kết hợp với Advanced Custom Fields (ACF). ACF mang lại cho WordPress những siêu năng lực, nhưng bạn vẫn đang phải cấu hình trong "ngôi nhà" của người khác. Sanity hoạt động theo chiều ngược lại. Bạn viết một schema bằng mã nguồn để định nghĩa chính xác mô hình nội dung của mình trông như thế nào, và Sanity sẽ xây dựng giao diện chỉnh sửa dựa trên những quyết định đó.

Tôi đã tận dụng sự kiểm soát đó để xây dựng một trình xây dựng trang (page builder) đơn giản từ các khối (blocks) có thể tái sử dụng. Tôi định nghĩa một phần hero một lần. Tôi định nghĩa một thanh trượt testimonial một lần. Tôi định nghĩa một lưới card một lần. Giờ đây, tôi có thể lắp ráp các trang mới bằng cách xếp chồng các khối đó theo bất kỳ thứ tự nào mà không cần viết mã mới hay chạm vào template của trang.

Sự khác biệt trong tư duy là rất quan trọng. Với WordPress, tôi thường cảm thấy mình đang vật lộn với một công cụ vốn dĩ muốn làm một blog. Với Sanity, tôi cảm thấy mình đang xây dựng phần mềm. Nội dung trở thành dữ liệu có cấu trúc sạch sẽ thay vì các đoạn HTML được định dạng trộn lẫn với các shortcode. Các mô tả dự án của tôi tồn tại dưới dạng các đối tượng có thể di chuyển, mà tôi có thể đưa vào một ứng dụng di động hoặc một bản tin (newsletter) nếu muốn.

Một quy trình triển khai gọn gàng

Quy trình WordPress cũ của tôi là một mớ hỗn độn của việc tải lên qua FTP, các subdomain staging và các bản cập nhật plugin luôn có vẻ như sẽ bị lỗi vào thời điểm tồi tệ nhất. Tôi đã phải giữ một danh sách kiểm tra trong đầu chỉ để xuất bản một bản sửa lỗi đánh máy.

Quy trình mới rất ngắn gọn:

  • Tôi thực hiện các thay đổi ở máy cục bộ và thấy chúng ngay lập tức.
  • Tôi commit lên GitHub khi mã nguồn đã ổn.
  • Vercel nhận lệnh push và tự động triển khai trang web.

Không có trình khách FTP. Không có cơ sở dữ liệu staging để đồng bộ hóa. Kho lưu trữ (repository) chính là nguồn sự thật duy nhất (source of truth).

Nội dung cũng hoạt động theo cách tương tự. Khi tôi xuất bản hoặc cập nhật một bài viết trong Sanity, một webhook sẽ báo cho Vercel để xây dựng lại trang web. Các trang tĩnh được tái tạo với nội dung mới, và CDN được cập nhật mà tôi không cần chạm vào máy chủ. Mọi thứ luôn đồng bộ mà không cần sao chép thủ công, xuất dữ liệu, hay cầu nguyện rằng việc di chuyển cơ sở dữ liệu plugin thực sự thành công.

Kết nối thiết kế và mã nguồn bằng tokens

Một trong những bước đột phá thầm lặng trong lần xây dựng lại này là việc thiết lập một hệ thống token chuẩn chỉnh. Tôi giữ một tệp JSON duy nhất quản lý mọi màu sắc, thang đo kiểu chữ (type scale) và giá trị khoảng cách trong trang web. Tệp đó là "ông chủ".

Tôi sử dụng Token Studio để đưa chính những giá trị đó trực tiếp vào Figma. Khi tệp thiết kế của tôi ghi là surface-default, nó đang trỏ đến chính xác con số mà mã nguồn sử dụng. Một đoạn script nhỏ sẽ chuyển đổi JSON thành các thuộc tính tùy chỉnh CSS (CSS custom properties) tại thời điểm build, vì vậy các stylesheet của tôi sẽ tham chiếu đến các biến như --color-surface-default thay vì các mã hex được viết cứng.

Đây là lý do tại sao điều đó quan trọng trong thực tế. Nếu tôi nhận ra màu đỏ thương hiệu của mình hơi quá gắt trên màn hình di động, tôi chỉ cần thay đổi một giá trị trong tệp JSON. Thư viện Figma sẽ cập nhật. CSS sẽ cập nhật. Mọi thực thể trên toàn bộ trang web đều cập nhật. Tôi không cần phải dùng lệnh grep để tìm kiếm khắp nơi.