การพัฒนา Personal Website ด้วย Next.js 15 + Tailwind CSS: จาก Zero to Production
หลังจากที่ตัดสินใจสร้าง personal website และ blog ขึ้นมาใหม่ วันนี้จึงมาแชร์ประสบการณ์การพัฒนา aoddy.com ตั้งแต่เริ่มต้นจนไปถึงการ deploy production บน Vercel รวมถึงปัญหาต่างๆ ที่เจอระหว่างทาง และการแก้ไขทีละขั้นตอน
🎯 Project Overview และเป้าหมาย
เป้าหมายหลักของการสร้าง website นี้คือ:
- Personal Branding: สร้าง online presence ที่เป็นตัวตนของตัวเอง
- Blog Platform: เขียน blog เกี่ยวกับ programming และ technology
- Portfolio Showcase: แสดงผลงานและทักษะการเขียนโปรแกรม
- Modern Tech Stack: ใช้เทคโนโลยีล่าสุดเพื่อเรียนรู้และทดลอง
เทคโนโลยีที่เลือกใช้:
- Frontend: Next.js 15.5.2 (App Router)
- Styling: Tailwind CSS
- Typography: Roboto + Noto Sans Thai
- Content Management: Markdown files
- Deployment: Vercel
- Language: TypeScript
- AI Development Assistant: Qoder IDE
🤖 Phase 0: AI-Powered Development with Qoder
การใช้ Qoder IDE เป็น Development Partner
ก่อนที่จะเริ่มเขียนโค้ด สิ่งแรกที่ทำคือการใช้ Qoder AI ช่วยในการวางแผนและสร้าง project structure ซึ่งกลายเป็นจุดเปลี่ยนที่สำคัญในการพัฒนา
สร้าง REQUIREMENTS.md ด้วย AI
Qoder ช่วยสร้าง comprehensive project requirements ที่ครอบคลุม:
# REQUIREMENTS.md (Generated by Qoder)
## Project Overview
- Personal blog website with modern tech stack
- Mobile-first responsive design
- SEO optimization
- Thai language support
## Technical Requirements
- Next.js 15+ with App Router
- TypeScript strict mode
- Tailwind CSS for styling
- Markdown-based content management
ประโยชน์ของการใช้ AI ในการพัฒนา
1. Rapid Prototyping
- สร้าง component structure ได้รวดเร็ว
- Generate boilerplate code ที่มีคุณภาพ
- ลดเวลาในการ setup project เหลือเพียง 30%
2. Code Quality & Best Practices
// Qoder แนะนำ TypeScript interfaces ที่ comprehensive
export interface BlogPost {
slug: string;
title: string;
excerpt: string;
date: string;
readTime: string;
tags: string[];
featured: boolean;
author: string;
content?: string;
heroImage?: string; // AI suggested this for better UX
}
3. Problem-Solving Assistance
- วิเคราะห์ errors และเสนอแนะวิธีแก้ไข
- ช่วยหา root cause ของปัญหาได้เร็วขึ้น
- แนะนำ alternative approaches ที่ดีกว่า
4. Documentation & Comments
// AI-generated documentation
/**
* Extracts the first image from markdown content for hero backgrounds
* @param content - Raw markdown content string
* @returns Image URL or undefined if no image found
*/
function extractHeroImage(content: string): string | undefined {
const imageRegex = /!\[.*?\]\((.*?)(?:\s+".*?")?\)/;
const match = content.match(imageRegex);
return match ? match[1] : undefined;
}
AI-Assisted Development Workflow
- Planning Phase: Qoder ช่วยวิเคราะห์ requirements และแนะนำ architecture
- Implementation: Generate starter code และ suggest improvements
- Debugging: วิเคราะห์ error messages และเสนอวิธีแก้ไข
- Optimization: แนะนำ performance improvements และ best practices
- Documentation: สร้าง README, comments, และ documentation
ตัวอย่างการช่วยแก้ปัญหาจริง
ปัญหา: ESLint errors ใน production build
Error: `'` can be escaped with `'`, `‘`, `'`, `’`
Qoder Analysis:
- ชี้ให้เห็นว่าเป็นปัญหา react/no-unescaped-entities
- แนะนำการใช้ HTML entities แทน straight quotes
- ให้วิธีการแก้ไขแบบ systematic ทั้ง codebase
ผลลัพธ์: แก้ไขได้ครบทุกไฟล์ และ build ผ่าน successfully
ROI ของการใช้ AI ในการพัฒนา
เวลาที่ประหยัดได้:
- Project Setup: 70% faster (จาก 2 วัน เหลือ 0.6 วัน)
- Debugging: 50% faster (เพราะได้ hints ที่แม่นยำ)
- Documentation: 80% faster (auto-generate จาก code)
- Code Review: 60% faster (AI pre-check quality)
คุณภาพที่ดีขึ้น:
- Consistent Code Style: AI enforce best practices
- Better Error Handling: Comprehensive error scenarios
- Documentation Coverage: ครบถ้วนและเป็นปัจจุบัน
- Performance Optimization: Suggestions for improvements
AI Development Best Practices
- Clear Communication: อธิบาย context และ requirements ให้ชัดเจน
- Iterative Refinement: ใช้ feedback loop เพื่อปรับปรุง output
- Human Oversight: Review และ test ทุก AI-generated code
- Learn from AI: ศึกษาเหตุผลเบื้องหลัง suggestions
- Combine Strengths: ใช้ AI ช่วยงานที่เหมาะสม, human handle creative decisions
🚀 Phase 1: Project Setup และ Architecture
การเริ่มต้นโปรเจค
เริ่มต้นด้วยการสร้าง Next.js project ใหม่:
npx create-next-app@latest aoddy.com --typescript --tailwind --eslint --app
cd aoddy.com
npm run dev
โครงสร้าง Directory
จัดระเบียบ project structure ให้เป็นระบบ:
src/
├── app/
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Homepage
│ ├── blog/
│ │ ├── page.tsx # Blog listing
│ │ └── [slug]/
│ │ └── page.tsx # Individual blog post
│ └── globals.css # Global styles
├── components/
│ ├── Logo.tsx # Logo component
│ └── ThaiText.tsx # Thai text component
└── lib/
└── blog.ts # Blog utilities
Core Dependencies
เพิ่ม dependencies ที่จำเป็น:
{
"dependencies": {
"gray-matter": "^4.0.3",
"remark": "^15.0.1",
"remark-html": "^16.0.1"
}
}
🎨 Phase 2: Design System และ UI Implementation
Custom Color Palette
สร้าง color palette ที่สะท้อนตัวตนและเป็น brand identity:
// tailwind.config.ts
colors: {
primary: {
500: '#1e81b0', // Main blue - professional และ trustworthy
},
cream: {
500: '#eeeee4', // Warm neutral - เพิ่มความอบอุ่น
},
orange: {
500: '#e28743', // Accent orange - energy และ creativity
},
accent: {
500: '#eab676', // Light orange - supporting color
}
}
Modern Design Implementation
ออกแบบ UI ด้วยหักมุมของ Modern Minimalism:
- Typography Hierarchy: ใช้ Roboto สำหรับ clean readability
- Glass Effects: เพิ่ม backdrop-blur เพื่อความทันสมัย
- Gradient Elements: สร้าง visual interest ด้วย gradient text
- Card Design: Hover effects และ subtle shadows
- Responsive Design: Mobile-first approach
/* ตัวอย่าง Glass Effect */
.glass {
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(8px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
📝 Phase 3: Blog System Development
Markdown-based Content Management
เลือกใช้ Markdown files แทน CMS เพื่อ:
- Simplicity: ไม่ซับซ้อน ไม่ต้องพึ่งพา database
- Version Control: track changes ได้ด้วย Git
- Performance: static generation = faster loading
- Flexibility: เขียนได้ทุกที่ sync ได้ทุกเครื่อง
Blog Structure Implementation
สร้าง blog utilities สำหรับจัดการ content:
// src/lib/blog.ts
export interface BlogPost {
slug: string;
title: string;
excerpt: string;
date: string;
readTime: string;
tags: string[];
featured: boolean;
author: string;
content?: string;
heroImage?: string;
}
export function getAllPosts(): BlogPost[] {
// Read และ parse Markdown files
// Sort by date descending
// Extract frontmatter metadata
}
Dynamic Routes Setup
ใช้ Next.js App Router สำหรับ dynamic blog routes:
// src/app/blog/[slug]/page.tsx
export async function generateStaticParams() {
const posts = getAllPosts();
return posts.map((post) => ({
slug: post.slug,
}));
}
🌏 Phase 4: Thai Language Support
Typography Challenges
เจอปัญหาการแสดงผล Thai fonts ที่ไม่สวย เลยต้องแก้ไข:
Noto Sans Thai Integration
// src/app/layout.tsx
import { Roboto, Noto_Sans_Thai } from "next/font/google";
const notoSansThai = Noto_Sans_Thai({
subsets: ["thai"],
variable: '--font-noto-sans-thai',
weight: ['300', '400', '500', '700'],
display: 'swap',
});
CSS Font Configuration
/* Global CSS สำหรับ Thai support */
.thai-text {
font-family: var(--font-noto-sans-thai), 'Noto Sans Thai', system-ui, sans-serif;
text-rendering: optimizeLegibility;
font-feature-settings: "liga" 1, "kern" 1;
}
.font-mixed {
font-family: var(--font-noto-sans-thai), var(--font-roboto),
'Noto Sans Thai', 'Roboto', system-ui, sans-serif;
}
Smart Thai Text Component
สร้าง component ที่ detect Thai characters อัตโนมัติ:
// src/components/ThaiText.tsx
const hasThaiCharacters = (text: string): boolean => {
const thaiRange = /[\u0E00-\u0E7F]/;
return thaiRange.test(text);
};
export const ThaiText: React.FC<ThaiTextProps> = ({ children, className }) => {
const textContent = React.Children.toArray(children).join('');
const hasThaiText = hasThaiCharacters(textContent);
const fontClass = hasThaiText ? 'font-mixed' : '';
// ...
};
🖼️ Phase 5: Image Optimization และ Visual Enhancements
Blurred Background Implementation
เพิ่มความสวยงามด้วย blurred background images:
// Extract first image from blog content
function extractHeroImage(content: string): string | undefined {
const imageRegex = /!\[.*?\]\((.*?)(?:\s+".*?")?\)/;
const match = content.match(imageRegex);
return match ? match[1] : undefined;
}
Next.js Image Optimization
{post.heroImage ? (
<>
<Image
src={post.heroImage}
alt={`${post.title} background`}
fill
className="object-cover blur-sm scale-110"
sizes="(max-width: 768px) 100vw, 50vw"
/>
<div className="absolute inset-0 bg-black/30"></div>
</>
) : (
<div className="bg-gradient-to-br from-primary-100 to-primary-200"></div>
)}
🚀 Phase 6: Production Deployment
Vercel Configuration
เตรียม project สำหรับ Vercel deployment:
// next.config.js - Optimized for Vercel
const nextConfig = {
experimental: {
optimizePackageImports: ['lucide-react'],
},
images: {
formats: ['image/webp', 'image/avif'],
qualities: [75, 90, 100],
},
trailingSlash: true,
};
Security และ Performance Headers
// vercel.json
{
"headers": [
{
"source": "/(.*)",
"headers": [
{"key": "X-Content-Type-Options", "value": "nosniff"},
{"key": "X-Frame-Options", "value": "DENY"},
{"key": "X-XSS-Protection", "value": "1; mode=block"}
]
}
]
}
🐛 ปัญหาที่เจอและการแก้ไข
1. ESLint Quote Escaping Errors
ปัญหา: Vercel build fail เพราะ unescaped quotes ใน JSX
Error: `'` can be escaped with `'`, `‘`, `'`, `’`.
แก้ไข: เปลี่ยน quotes ให้เป็น HTML entities
// Before
<span>Hello, I'm Aoddy</span>
// After
<span>Hello, I'm Aoddy</span>
2. Homepage Blog Posts Display Issue
ปัญหา: Homepage แสดง hardcoded sample posts แทน real content
แก้ไข: เปลี่ยนมาใช้ dynamic data loading
// Before: hardcoded data
const articles = [{ title: "Sample post" }];
// After: dynamic loading
const blogPosts = getAllPosts();
const recentPosts = blogPosts.slice(0, 2);
3. Thai Font Not Applied
ปัญหา: Thai text ยังใช้ default font แทน Noto Sans Thai
แก้ไข: เพิ่ม thai-text
class ใน components ที่มี Thai content
<h3 className="text-xl font-semibold thai-text">
{post.title}
</h3>
<p className="text-gray-600 thai-text">
{post.excerpt}
</p>
📊 Performance Results
หลังจาก optimize แล้ว ได้ผลลัพธ์:
Build Statistics
- Total bundle size: 102 kB shared + 173 B page-specific
- Static pages generated: 10 pages
- Image optimization: WebP/AVIF automatic conversion
- Font loading: Optimized with display: swap
Core Web Vitals
- First Load JS: ~111 kB (ถือว่าดี)
- Static Generation: ทุกหน้าถูก pre-render
- SEO Ready: Metadata และ OpenGraph complete
🎉 สิ่งที่ได้เรียนรู้
Technical Learnings
- Next.js 15 App Router: Architecture ใหม่ที่ powerful กว่าเดิม
- Tailwind CSS: Utility-first approach ที่เร็วและยืดหยุ่น
- Typography: การจัดการ multi-language fonts อย่างถูกต้อง
- Performance: Image optimization และ bundle size management
- Deployment: Modern deployment workflow ด้วย Vercel
- AI-Powered Development: การใช้ Qoder เพิ่มประสิทธิภาพการเขียนโค้ด
Development Workflow
- AI-Assisted Planning: ใช้ Qoder วางแผน architecture และ design system ก่อน
- Incremental Development: พัฒนาทีละ feature, test ให้ผ่านก่อนต่อ
- Typography First: Setup fonts และ typography ตั้งแต่เริ่มต้น
- Content Strategy: วางแผน content management ให้ชัดเจน
- Production Ready: เตรียม deployment configuration ตั้งแต่เริ่มต้น
- AI Quality Assurance: ใช้ Qoder review code quality และ suggest improvements
🔮 Next Steps และ Future Enhancements
Short-term Improvements
- SEO Optimization: Structured data และ sitemap
- Performance: Code splitting และ lazy loading
- Analytics: เพิ่ม visitor tracking
- RSS Feed: สำหรับ blog subscribers
Long-term Vision
- Multi-language Support: English และ Thai content
- Interactive Components: Dynamic demos และ code playgrounds
- Advanced Search: Full-text search ใน blog posts
- Comment System: Community engagement features
✨ สรุป
การสร้าง personal website เป็นการเดินทางที่น่าสนใจมาก จากที่เริ่มต้นด้วย idea ง่ายๆ ก็กลายเป็น modern web application ที่มีความสามารถครบครัน
Key Takeaways:
- Modern Tech Stack ช่วยให้การพัฒนาเร็วขึ้นและ maintainable
- Design System ที่ดีทำให้ UI/UX consistent และ professional
- Thai Typography ต้องใส่ใจในรายละเอียดเพื่อให้อ่านง่าย
- Performance Optimization สำคัญสำหรับ user experience
- Deployment Automation ช่วยลดความผิดพลาดและเพิ่มความเร็ว
- AI-Powered Development เพิ่มประสิทธิภาพและคุณภาพอย่างมาก
ตัว website ตอนนี้พร้อมใช้งานแล้วบน aoddy.com และจะมี blog posts ใหม่ๆ เรื่อย ๆ เกี่ยวกับการพัฒนา software และเทคโนโลยีต่าง ๆ
หวังว่าประสบการณ์นี้จะเป็นประโยชน์สำหรับคนที่กำลังคิดจะสร้าง personal website เหมือนกัน! 🚀
Resources:
- Next.js Documentation
- Tailwind CSS
- Vercel Deployment Guide
- Google Fonts - Noto Sans Thai
- Qoder AI IDE - AI-powered development assistant