Cách xây dựng juanchi.dev với bộ công nghệ mới nhất 2025: Next.js 16, React 19, Tailwind v4 và Railway

07 tháng 4, 2026·5 phút đọc

Bài viết chia sẻ kinh nghiệm thực tế khi phát triển portfolio cá nhân với công nghệ Next.js 16, React 19, Tailwind v4 và hệ thống triển khai Railway. Tác giả phân tích chi tiết các thử thách, lỗi gặp phải và cách vượt qua khi làm việc với stack công nghệ tiên tiến nhất năm 2025.

Cách xây dựng juanchi.dev với bộ công nghệ mới nhất 2025: Next.js 16, React 19, Tailwind v4 và Railway

Cách xây dựng juanchi.dev với bộ công nghệ mới nhất 2025: Next.js 16, React 19, Tailwind v4 và Railway

Trong quá trình phát triển juanchi.dev, điều trăn trở lớn nhất của tác giả là nên dùng stack công nghệ đã được kiểm chứng hay liều lĩnh thử nghiệm những công nghệ mới nhất và chấp nhận rủi ro? Cuối cùng, tác giả quyết định chọn “liều”, áp dụng Next.js 16, React 19, Tailwind CSS v4 cùng Railway để xây dựng portfolio cá nhân và chia sẻ thực tế những khó khăn, trải nghiệm đúc kết được trong suốt quá trình triển khai.

Khởi đầu tự tin nhưng không dễ dàng với Tailwind v4

Với vài dòng lệnh cơ bản, dự án Next.js đã được scaffold nhanh chóng, thế nhưng Tailwind CSS v4 gây bất ngờ khi không còn dùng file cấu hình tailwind.config.js như trước đó nữa mà chuyển toàn bộ cấu hình về CSS với cú pháp @theme. Điều này ban đầu khiến tác giả mất đến gần 2 tiếng mới hiểu ra cách tùy biến màu sắc hay kiểu chữ trong phiên bản mới.

"Với v4, file CSS chính là file cấu hình, khác biệt này có thể gây bối rối lúc đầu nhưng khi đã quen thì rất tuyệt."

React 19 và Server Components: cơ hội lẫn thử thách

Bài toán chính là làm sao kết hợp linh hoạt giữa Server Components (phần tĩnh hoặc xử lý dữ liệu server-side) và Client Components (phần cần tương tác, animation). Tác giả chọn dùng pattern “wrapper client - nội dung server” để xử lý các animation bằng framer-motion, vì thư viện này cần thao tác DOM ở client và không chạy trong server components.

Ví dụ mã nguồn phần animation wrapper client-side với React 19:

'use client'
import { motion } from 'framer-motion'
import { ReactNode } from 'react'

interface AnimatedSectionProps {
  children: ReactNode
  delay?: number
}

export function AnimatedSection({ children, delay = 0 }: AnimatedSectionProps) {
  return (
    <motion.div
      initial={{ opacity: 0, y: 24 }}
      whileInView={{ opacity: 1, y: 0 }}
      viewport={{ once: true }}
      transition={{ duration: 0.5, delay, ease: 'easeOut' }}
    >
      {children}
    </motion.div>
  )
}

Hệ thống quản lý dự án với MDX và phát sinh tĩnh

Thay vì dùng CMS hoặc database, tác giả quyết định lưu dữ liệu dự án bằng các file MDX trong repo, đọc trực tiếp file này từ server bằng fs.readdirSync và sử dụng thư viện gray-matter để trích xuất metadata. Cách làm này giúp giảm thiểu phụ thuộc bên ngoài, phù hợp cho portfolio cá nhân nhỏ gọn.

Railway: triền khai tưởng đơn giản nhưng không phải vậy

Railway là nền tảng yêu thích để deploy nhờ tính tiện dụng và tự động hóa. Tuy nhiên, vấn đề nảy sinh khi Next.js 16 chuyển sang hỗ trợ nhiều chế độ output; nếu bật output: 'export' (xuất build tĩnh hoàn toàn) thì fs.readdirSync không thể đọc file vì thư mục gốc không được build kèm theo.

Cách giải quyết:

  • Chuyển sang chế độ Node.js (SSR), không dùng chế độ export tĩnh nữa.
  • Hoặc pre-generate dữ liệu trước khi build (trong trường hợp muốn xuất tĩnh).

Cuối cùng tác giả chọn giải pháp Node.js runtime để giữ endpoint contact với logic server-side.

Một đoạn cấu hình next.config.ts trong dự án:

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  images: {
    remotePatterns: [{ protocol: 'https', hostname: 'github.com' }],
  },
  experimental: {
    optimizePackageImports: ['framer-motion', 'lucide-react'],
  },
}

export default nextConfig

Form liên hệ dùng Server Actions trong Next.js 15+ và React 19

Server Actions được nâng lên thành tính năng chính thức trong các phiên bản mới, giúp gửi email trực tiếp từ server khi người dùng gửi form mà không cần viết API riêng biệt.

Mẫu function xử lý form:

'use server'
import { Resend } from 'resend'
import { z } from 'zod'

const resend = new Resend(process.env.RESEND_API_KEY)

const ContactSchema = z.object({
  name: z.string().min(2).max(100),
  email: z.string().email(),
  message: z.string().min(10).max(2000),
})

export async function sendContactEmail(
  prevState: { success: boolean; error?: string } | null,
  formData: FormData
) {
  const raw = {
    name: formData.get('name'),
    email: formData.get('email'),
    message: formData.get('message'),
  }

  const parsed = ContactSchema.safeParse(raw)
  if (!parsed.success) {
    return { success: false, error: 'Dữ liệu không hợp lệ. Vui lòng kiểm tra lại.' }
  }

  try {
    await resend.emails.send({
      from: '[email protected]',
      to: '[email protected]',
      subject: `Liên hệ mới: ${parsed.data.name}`,
      text: `Từ: ${parsed.data.email}\n\n${parsed.data.message}`,
    })
    return { success: true }
  } catch (error) {
    console.error('Lỗi khi gửi email:', error)
    return { success: false, error: 'Lỗi gửi, thử lại sau.' }
  }
}

Tổng kết những trở ngại chính

  • Tailwind v4 thay đổi các utility, gây hiệu ứng kích thước font khác biệt, buộc tác giả dành thời gian debug.
  • Framer-motion với React 19 có lỗi hydration ban đầu, phải cập nhật version mới.
  • Railway bị lỗi healthcheck timeout vì server mất thời gian load lần đầu, cần tăng timeout lên 30 giây.
  • Thay đổi typescript types trong Next.js 16 khiến tham số params khi dùng với layouts và pages giờ là Promise, gây lỗi khi migrate.

Có nên thử lại?

Tác giả khẳng định: hoàn toàn có, vì làm với bleeding edge tech buộc ta đọc hiểu sâu hơn về cách hoạt động, không thể copy-paste đại trà. Kết quả là một portfolio cá nhân với hiệu năng cao (tải dưới 1,2 giây, điểm Lighthouse đạt 98/100), chi phí vận hành thấp (dưới 5 USD/tháng) và đặc biệt là hiểu rõ mọi khía cạnh dự án từ đầu đến cuối.

Công nghệ mới tuy khó khăn ban đầu, nhưng đó chính là lợi thế cạnh tranh dài hạn.


Mã nguồn juanchi.dev sẽ được công khai trên GitHub sau khi tác giả hoàn thiện và dọn dẹp, đây là trải nghiệm quý báu với công nghệ web hiện đại năm 2025.

Bài viết gốc được đăng tại juanchi.dev

Bài viết được tổng hợp và biên soạn bằng AI từ các nguồn tin tức công nghệ. Nội dung mang tính tham khảo. Xem bài gốc ↗