ข้ามไปยังเนื้อหา

Project และ .astro Files

โปรเจกต์ Astro ทั่วไปมีโครงสร้างเล็ก ๆ ที่เป็น convention:

my-site/
├── astro.config.mjs # config: integrations, adapter, output mode
├── src/
│ ├── pages/ # file-based routing — แต่ละไฟล์คือหนึ่ง route
│ ├── components/ # component แบบ .astro (และ framework) ที่ reuse ได้
│ ├── layouts/ # เชลล์ของหน้าที่ใช้ร่วมกัน
│ ├── content.config.ts # config ของ content collections (Astro 5+)
│ └── styles/
└── public/ # static assets ที่ serve ตรง ๆ (favicon, robots.txt)

สองโฟลเดอร์ที่เป็นแกนหลัก:

  • src/pages/ คือ file-based routing: src/pages/index.astro/, src/pages/about.astro/about, src/pages/blog/[slug].astro/blog/:slug ตำแหน่งของไฟล์ คือ route
  • public/ ถูก copy ไปยัง output ตรง ๆ — ไฟล์ในนี้ถูก serve ที่ root โดยไม่ผ่านการประมวลผล

ไฟล์ .astro คือ component format ของ Astro เอง มีสองส่วนคั่นด้วย code fence (---):

---
// 1. component script (frontmatter) รันบน SERVER เท่านั้น
// JavaScript/TypeScript ตรงนี้: imports, ดึงข้อมูล, props, logic
import Card from '../components/Card.astro';
const title = "Latest posts";
const posts = await fetch('https://api.example.com/posts').then((r) => r.json());
---
<!-- 2. template กลายเป็น HTML ใช้ { } เพื่อฝัง JS expression -->
<h1>{title}</h1>
<ul>
{posts.map((post) => <Card title={post.title} />)}
</ul>

Mental model สำคัญ:

  • ทุกอย่าง เหนือ --- ตัวที่สองคือ component script — รันครั้งเดียว บน server ตอน build (หรือแต่ละ request สำหรับหน้า on-demand) ตรงนี้คือที่ที่คุณดึงข้อมูล import component และคำนวณค่า ไม่มีอะไรในนี้ถูกส่งไป browser
  • ทุกอย่าง ใต้ นั้นคือ template — HTML ที่มี { } expression หย่อน JavaScript ลงไป นี่คือสิ่งที่กลายเป็น HTML ที่ render ออกมา
flowchart LR
  script["--- frontmatter ---
component script
(server เท่านั้น)"] --> compute["ดึงข้อมูล, คำนวณ props"]
  compute --> template["template (HTML + { } expression)"]
  template --> html["HTML ที่ render แล้ว"]
สองครึ่งของไฟล์ .astro

เพราะ script รันบน server คุณจึง await ที่ระดับบนสุดได้ — fetch จาก API หรือ database ตรง ๆ ใน component โดยไม่ต้องมี useEffect ไม่ต้องมี loading state ไม่ต้องวิ่งไป client รอบใหม่ ข้อมูลอยู่พร้อมแล้วตอนที่ HTML ถูก build

template .astro คือ HTML ที่ valid บวกกับ expression คล้าย JSX ถ้าคุณวาง HTML ธรรมดาลงในไฟล์ .astro ก็ทำงานได้เลย คุณเพิ่มความ dynamic ด้วย { } (expression), {condition && <div/>} (conditional) และ {items.map(...)} (loop) — syntax แบบ expression เดียวกับที่เห็นในตัวอย่าง landing ต่างจาก JSX ตรงที่คุณใช้ชื่อ attribute แบบ HTML มาตรฐาน (class ไม่ใช่ className)

routing ใน Astro ทำงานยังไง?
อะไรรันใน frontmatter (code เหนือ `---` ตัวที่สอง) ของไฟล์ .astro?
ทำไมคุณถึงใช้ top-level `await` ใน component script ของ .astro ได้?
template .astro ในเชิง syntax คืออะไร?