Frontmatter & Template
React component มีสองส่วนเชิงตรรกะ คือ function body (ที่คุณประกาศตัวแปร เรียก hook และรัน logic) กับ JSX ที่ return ออกมา (สิ่งที่ render) Astro component สะท้อนการแบ่งนี้ด้วยเส้นคั่น (fence) ที่ชัดเจน
---// frontmatter: JS/TS that runs at build or server time---<!-- template: HTML-first markup rendered to static HTML -->คู่ของ --- เรียกว่า component script หรือ frontmatter ทุกอย่างที่อยู่ระหว่าง fence คือ TypeScript/JavaScript ล้วน ๆ ส่วนทุกอย่างที่อยู่หลัง --- ปิดท้ายคือ template ที่เป็น superset ของ HTML ที่คุณฝัง expression ได้ด้วย {...}
Frontmatter: component script
หัวข้อที่มีชื่อว่า “Frontmatter: component script”ให้คิดถึง frontmatter เหมือนส่วนบนของ React function แต่ไม่มี hook และ event handler สิ่งที่คุณทำได้คือ:
- import component อื่น ๆ, utility และไฟล์ข้อมูล
- ดึงข้อมูลด้วย
await(ทั้ง component ทำงานบนเซิร์ฟเวอร์/ตอน build) - destructure props จาก
Astro.props - ประกาศตัวแปร local ที่ template จะอ่านไปใช้
// Card.jsx (function body = "frontmatter")import { formatDate } from './utils';
export default function Card({ title, date }) { // runs in the browser on every render const formatted = formatDate(date);
return ( <div className="card"> <h2>{title}</h2> <time>{formatted}</time> </div> );}---// Card.astro (frontmatter = component script)import { formatDate } from './utils';
// runs ONCE at build time — never in the browserconst { title, date } = Astro.props;const formatted = formatDate(date);---<div class="card"> <h2>{title}</h2> <time>{formatted}</time></div>HTML template
หัวข้อที่มีชื่อว่า “HTML template”หลังจาก --- ที่ปิดท้าย คุณจะเขียน HTML ซึ่ง ไม่ใช่ JSX:
- ใช้
classไม่ใช่className - attribute แบบ boolean ทำงานตามวิธีมาตรฐานของ HTML
- self-closing tag เป็นไปตามกฎของ HTML (แต่ Astro ผ่อนปรนให้ ทั้ง
<img />และ<img>ใช้ได้) - ฝัง JavaScript expression ใด ๆ ด้วย
{expr}
---
const items = ["Astro", "React", "TypeScript"];
const hero = { title: "Welcome", subtitle: "Zero JS by default" };
---
<html lang="en">
<head><meta charset="utf-8" /><title>{hero.title}</title></head>
<body>
<h1>{hero.title}</h1>
<p>{hero.subtitle}</p>
<ul>
{items.map((item) => <li>{item}</li>)}
</ul>
</body>
</html>