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

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 เหมือนส่วนบนของ React function แต่ไม่มี hook และ event handler สิ่งที่คุณทำได้คือ:

  • import component อื่น ๆ, utility และไฟล์ข้อมูล
  • ดึงข้อมูลด้วย await (ทั้ง component ทำงานบนเซิร์ฟเวอร์/ตอน build)
  • destructure props จาก Astro.props
  • ประกาศตัวแปร local ที่ template จะอ่านไปใช้
React
// 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>
);
}
Astro
---
// Card.astro (frontmatter = component script)
import { formatDate } from './utils';
// runs ONCE at build time — never in the browser
const { title, date } = Astro.props;
const formatted = formatDate(date);
---
<div class="card">
<h2>{title}</h2>
<time>{formatted}</time>
</div>

หลังจาก --- ที่ปิดท้าย คุณจะเขียน HTML ซึ่ง ไม่ใช่ JSX:

  • ใช้ class ไม่ใช่ className
  • attribute แบบ boolean ทำงานตามวิธีมาตรฐานของ HTML
  • self-closing tag เป็นไปตามกฎของ HTML (แต่ Astro ผ่อนปรนให้ ทั้ง <img /> และ <img> ใช้ได้)
  • ฝัง JavaScript expression ใด ๆ ด้วย {expr}
Astro
---
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>
คุณจะเขียน `const data = await fetch('/api/posts')` ไว้ที่ไหนใน Astro component?
ชื่อ attribute ใดถูกต้องใน HTML template ของ Astro?
คุณเรียก React hook อย่าง useState ภายในบล็อก frontmatter ของ Astro ได้หรือไม่?
delimiter ที่ปิดท้ายบล็อก frontmatter ของ Astro คืออะไร?