Trong bối cảnh người dùng thường xuyên di chuyển giữa môi trường có và không có mạng, việc thiết kế ứng dụng hoạt động tốt khi offline trở thành yêu cầu bắt buộc. Bài viết này chia sẻ quy trình thực tế để triển khai Offline‑First cho một monorepo chứa cả Next.js (web) và Expo (mobile). 1. Xác định dữ liệu cần lưu trữ cục bộ - Phân loại state thành "critical" (đăng nhập, giỏ hàng, cài đặt người dùng) và "non‑critical" (danh sách bài viết, hình ảnh thumbnail). - Chỉ đồng bộ critical data ngay lập tức; non‑critical có thể tải nền khi có kết nối. 2. Chọn công cụ lưu trữ phù hợp - Web: IndexedDB qua thư viện idb hoặc Dexie.js để có API promise‑based. - Mobile: SQLite (expo‑sqlite) hoặc AsyncStorage cho dữ liệu nhỏ; dùng WatermelonDB khi cần quan hệ phức tạp. 3. Triển khai Service Worker cho Next.js - Cài đặt workbox‑webpack‑plugin trong next.config.js. - Cấu hình precache manifest cho các file tĩnh (JS, CSS, font). - Viết runtime caching strategy "stale‑while‑revalidate" cho API GET và "network‑only" cho mutation. - Đăng ký SW trong _app.tsx và xử lý sự kiện `sync` để đẩy hàng đợi mutation khi online. 4. Đồng bộ dữ liệu hai chiều - Tạo hàng đợi outbox (bảng outbox) lưu các thao tác CREATE/UPDATE/DELETE với timestamp. - Khi mạng khả dụng, worker đọc outbox, gọi API và xóa bản ghi sau khi thành công. - Xử lý xung đột bằng chiến lược "last‑write‑wins" kết hợp version vector hoặc server‑side merge. 5. UI phản hồi trạng thái kết nối - Hook `useOnlineStatus` dùng `navigator.onLine` (web) và `NetInfo` (React Native). - Hiển thị banner nhẹ, vô hiệu hóa nút gửi khi offline, cho phép thao tác cục bộ. 6. Kiểm thử và quan sát - Viết test integration với MSW (Mock Service Worker) để mô phỏng offline/online. - Sử dụng Sentry hoặc LogRocket để ghi log lỗi đồng bộ, thêm metric `sync_success_rate`. Lời khuyên áp dụng ngay: bắt đầu từ một feature nhỏ (ví dụ: lưu ghi chú) để验证 toàn bộ pipeline trước khi mở rộng ra toàn bộ ứng dụng. Việc tách biệt lớp dữ liệu (repository) khỏi UI giúp tái sử dụng logic đồng bộ cho cả web và mobile mà không lặp code.