สวัสดีครับ วันนี้ผมมาเขียนบล็อกแชร์ประสบการณ์การเปลี่ยนเว็บจาก Next.js มาเป็น Astro ว่าทำไมถึงเลือกเปลี่ยน โดยเป้าหมายหลักๆ คือ
ทำไมผมถึงเลือกใช้ Astro?
- อย่างแรกคือ อยากลองอะไรใหม่ๆ และ Astro ก็เป็นหนึ่งในตัวเลือกที่อยู่ใน list มานานแล้ว
 - สะดวกในการจัดการ Content โดยใช้ Markdown และ MDX (ซึ่งจริงๆ ก็เหมือนกับปัจจุบัน ที่ใช้ Next.js + MDX)
 - รองรับ View Transitions API
 - ใช้ UI framework ตัวไหนก็ได้ ไม่จำกัด เช่น React, Vue, Svelte
 - มีแผนในการทำ ระบบ Auth และก็ server-side ทำให้เลือกใช้ Astro ที่ไม่เลือกใช้ Next.js ก็เพราะ งานหลักก็เจอ Next.js ทำให้งาน hobby เราก็อยากเลือก tool อื่นๆ เพื่อความหลากหลายบ้าง
 
Migration
เนื่องจากผมมีช่วงที่ย้ายไป Ghost อยู่พักนึง และก็อีกส่วนที่ใช้ Next.js ขั้นตอนการย้าย สำหรับ Next.js นั้นไม่ยาก ส่วนหน้าเว็บ พยายามให้เหมือนเดิม มีการปรับ re-design บ้างเล็กน้อย
- ในส่วนของ content ผมเป็น Markdown + MDX อยู่แล้ว สามารถที่จะย้ายได้เลย
 - ในส่วนของ content ที่เขียนไว้ที่ Ghost ผมใช้วิธี นั่ง rewrite ใหม่ และเลือกบาง content มาเท่านั้น
 
จากนั้น ก็กำหนด Content Collection ให้ตรงกับ frontmatter
import { defineCollection, reference, z } from 'astro:content'
const blog = defineCollection({  type: 'content',  schema: () =>    z.object({      title: z.string(),      category: z.string(),      tags: z.array(z.string()),      authors: z.array(reference('author')).default(['default']),      // Transform string to Date object      date: z.coerce.date(),      cover: z.string().optional(),      draft: z.boolean().optional(),      postLayout: z        .enum(['simple', 'column'])        .default(POST_METADATA.defaultLayout as 'simple' | 'column')    })})
export const collections = { blog }ผมเริ่มโดยการ fork project tailwind-astro-starting-blog และนำมา customize ต่อ ส่วนโปรเจ็คอื่นๆ ก็มีดูเป็นไอเดีย นำมาใช้บ้าง เช่น
Motion
ใช้ตัว motion.dev แบบ JavaScript เนื่องจากตัว component ผม .astro ก็ใส่ code ใน tag <script>
<script>import { animate, inView, stagger } from 'motion'
animate('<selector>', { opacity: 0.25, y: 10 })</script>Expressive Code
เป็นเหมือน Plugin มาช่วยจัดการเรื่องของ Syntax Highlighting
- แสดง Line Numbers หรือ hightlight แต่ละบรรทัดได้
 - มี Terminal Frames แล้วก็ code block title
 
ตัวอย่าง config สำหรับโชว์ line number และ ปรับแต่ง themes
import { defineConfig } from 'astro/config'import { pluginLineNumbers } from '@expressive-code/plugin-line-numbers'
export default defineConfig({  integrations: [    expressiveCode({      plugins: [pluginLineNumbers()],      themes: ['tokyo-night', 'slack-ochin', 'catppuccin-mocha'],      defaultProps: {        wrap: true,        showLineNumbers: true      }    })  ]})ในเมื่อในเว็บมีปุ่ม toggle theme ก็ต้องปรับ theme ให้ตรงเวลากดด้วย
if (newTheme === 'light') {  document.documentElement.setAttribute('data-theme', 'slack-ochin')} else {  document.documentElement.setAttribute('data-theme', 'catppuccin-mocha')}Theme ที่รองรับของ Expressive Code

Deployment
เราเลือกใช้ Vercel เหมือนเดิม เนื่องจากหลายๆ โปรเจ็คก็อยู่ที่นี่ การตั้งค่าให้ hosting Vercel ก็คือต้องใช้ Adapter นั่นเอง
npm install @astrojs/vercelตั้งค่า config
import { defineConfig } from 'astro/config'import vercel from '@astrojs/vercel/serverless'
export default defineConfig({  output: 'hybrid',  adapter: vercel()})เนื่องจากผมมีแผน ให้มีทั้ง Servier Side และส่วนที่เป็นบล็อกจะเป็น static ทำให้ตั้ง output เป็น hybrid คือให้มัน build static แต่ถ้าเราจะให้เป็น server side ก็ต้องไปกำหนด prerender ให้ไม่ตรง pre-render static page
export const prerender = falseสุดท้าย ฝากติดตามบล็อกใหม่ด้วยนะครับ ขอบคุณครับ
- Authors
 -  
 Chai Phonbopit
เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust