Astro และ Static site generator

/ 8 min read

Share on social media

astro-basic สามารถดู video ของหัวข้อนี้ก่อนได้ ดู video

Astro คืออะไร ?

Ref: https://astro.build/

Astro เป็น Web framework สมัยใหม่ที่ช่วยให้นักพัฒนาสามารถสร้าง web app ที่เร็วขึ้นโดยพยายามให้ web ใช้การ render JavaScript ที่น้อยลง (จากความสามารถของ Server site generator) โดยมี feature เด่นๆหลักๆคือ

  1. Island Architecture Astro ใช้วิธีการที่เรียกว่า “islands architecture” ซึ่งหมายความว่าหน้าเว็บส่วนใหญ่เป็น HTML แบบ static แต่มี interactive components (เช่น chatbox, form) ที่สามารถยังคงใช้งานร่วมกันบน Client ได้ ซึ่ง feature นี้จะสามารถ render ของ 2 อย่างออกจากกัน (Static components และ interactive components) แต่ยังคงสามารถพูดคุยไปมาหากันได้เหมือนเดิม ผ่านความสามารถของ Island เพื่อลดปริมาณ JavaScript ที่ต้องส่งไปยัง Browser ทำให้หน้าเว็บโหลดเร็วขึ้นและใช้ bandwidth น้อยลงได้ (อ่านเพิ่มเติมได้ที่ https://docs.astro.build/en/concepts/islands/)
astro-island
  1. Static Site Generator (SSG) Astro มาพร้อมกับความสามารถสร้างเว็บไซต์แบบ Static ออกมาได้ ผ่านความสามารถ build อย่าง Static Site Generator ซึ่งเหมาะสำหรับเว็บ Content อย่าง Blog, documentation, และเว็บไซต์อื่นๆ ที่เนื้อหาไม่เปลี่ยนแปลงบ่อยๆ โดย SSG ยังช่วยให้หน้าเว็บโหลดเร็วขึ้นและ SEO ดีขึ้นด้วยเช่นกัน

  2. Tailored JavaScript Delivery Astro ส่งเฉพาะ JavaScript ที่จำเป็นออกมาเท่านั้น ไม่เหมือนกับ Single Page Application อื่นๆ (SPA) ที่โหลด JavaScript ขนาดใหญ่มาแล้วจัดการทุกอย่างผ่าน Javascript แทน ไม่ว่าจะเป็นหน้าไหน Astro จะแบ่ง code ออกเป็นชิ้นเล็กๆ ที่ใช้กับแต่ละหน้าได้

ซึ่งสิ่งนี้ส่งผลต่อ Score ของ Pagespeed อย่างมากทั้งในเรื่องของ FCP, Blocking time เช่น mikelopster.dev แห่งนี้ที่มีการเปลี่ยนมาใช้ Astro

astro-pagespeed

Astro เหมาะสำหรับเว็บไซต์ที่เน้นประสิทธิภาพ SEO และประสบการณ์ผู้ใช้ที่รวดเร็วเป็นหลัก ไม่เหมาะสำหรับ web ที่จัดการ Content แบบ Dynamic ซึ่ง Framework SPA แบบดั้งเดิม (ไม่ว่าจะเป็น Vue, React, Angular, Svelte) อาจเหมาะสมกว่าในเคสนี้

สามารถอ่านเพิ่มเติมได้ที่ https://docs.astro.build/en/concepts/why-astro/

ในบทความนี้เราจะพูดถึงอะไรกันบ้าง

เราจะพาทุกคนมารู้จักกับ Astro กันตั้งแต่จุดเริ่มต้นว่า

  • สามารถ Start project Astro ยังไงได้บ้าง
  • แต่ละ Feature ของ Astro ตั้งแต่
    • Astro Component / การส่ง Props ผ่าน Component / การ import Component
    • Component Script
    • การทำ Route / Parameter path
    • การเขียน content ผ่าน markdown และการควบคุม content ผ่าน markdown
    • การจัดการ Layout และ Style
    • การ fetch ข้อมูลจาก Server
    • Client Site Script (สำหรับจัดการฝั่ง Client)

มารู้จักไปพร้อมๆกันครับ (เพื่อความรวดเร็ว สามารถดูเป็นฉบับ Video เพื่อ overview ดูก่อนได้เช่นกัน)

Setup Astro

Ref: https://docs.astro.build/en/install/auto/

มาลองเล่น Astro กันดีกว่า ลง project Astro ด้วย cli ด้วยคำสั่งเหล่านี้ได้

Terminal window
# create a new project with npm
npm create astro@latest
# create a new project with pnpm
pnpm create astro@latest
# create a new project with yarn
yarn create astro

สำหรับเริ่มต้นให้เลือกแบบ “Include sample file” เพื่อให้ project (เพื่อมาเรียกรู้ structure กัน) เลือก option ตามภาพนี้ได้

astro-install

หลังจากลงตามนี้เรียบร้อยเราจะได้ structure file หน้าตาประมาณนี้ออกมา

.
├── README.md
├── astro.config.mjs
├── package-lock.json
├── package.json
├── public
│   └── favicon.svg
├── src
│   ├── components
│   │   └── Card.astro
│   ├── env.d.ts
│   ├── layouts
│   │   └── Layout.astro
│   └── pages
│   └── index.astro
└── tsconfig.json

โดย

  • Folder หลักสำหรับจัดการ application คือ src
  • astro.config.mjs คือตัวจัดการ config หลักของ astro

** สำหรับใครอยากได้ Blog template แบบสำเร็จทีเดียว แนะนำให้เลือกแบบ Blog template จะได้ส่วนของ Markdown ออกมาด้วย

หลังจาก create project เสร็จให้เข้ามาใน directory project แล้ว run ด้วยคำสั่ง

Terminal window
npm run dev

ก็จะได้ผลลัพธ์แบบนี้ออกมา (default port ของ Astro คือ localhost:4321)

astro-start

ถ้าสามารถได้ผลลัพธ์แบบนี้ออกมาได้ ถือว่า create project ได้ถูกต้องเป็นที่เรียบร้อย

พื้นฐาน Astro

เราจะมาทำเว็บ Blog อย่างง่ายไปทีละ step กัน โดยในท้ายที่สุดเราจะทำให้เว็บ Blog ของเราสามารถดึงข้อมูลจาก API และแสดงผลออกมาได้

  • ที่สำคัญคือ Astro เองก็มี tutorial ภายใน document ของตัวเองไว้เช่นเดียวกัน สามารถเข้าไปอ่านและลองค่อยๆไล่ทีละ step ตาม document ของ Astro ได้เช่นกัน https://docs.astro.build/en/tutorial/0-introduction/

สร้าง astro component

Ref: https://docs.astro.build/en/tutorial/1-setup/3/

เราสามารถสร้างไฟล์ชื่อ .astro เพื่อเป็นการสร้าง Component สำหรับใช้งานในเว็บออกมาได้

  • ถ้าสร้างภายใน folder pages = เป็น Page Component ที่สามารถเปิดตาม Route ตามชื่อไฟล์ออกมาได้ (อ่านเพิ่มเติมได้ที่ https://docs.astro.build/en/core-concepts/astro-pages/ ซึ่งเดี๋ยวจะมีย้ำอีกทีในหัวข้อ markdown)
  • ถ้าสร้างภายนอก folder pages = เป็น Component ทั่วไปที่สามารถ import มาใช้ได้

เช่น หากเราสร้างไฟล์ที่ src/pages/about.astro หน้าตาประมาณนี้

<body>
<h1>Astro</h1>
<h1>Hello About page</h1>
</body>

ก็จะสามารถเปิดผ่าน localhost:4321/about ออกมาได้หน้าตาตาม html นี้ออกมา

astro-demo-01

Ref: https://docs.astro.build/en/tutorial/2-pages/1/

ในการ link ไปยังแต่ละหน้าสามารถใช้ tag <a> ในการ link ระหว่างหน้าได้เลย (เหมือน html ทั่วไปเลย) โดย

  • path จะยังอ้างอิงตาม Page Component ที่สร้างไว้

เช่นแบบนี้ลองเพิ่มที่หน้า index.astro

<a href="/">Home</a>
<a href="/about/">About</a>
<h1>About Me</h1>
<h2>... and my new Astro site!</h2>

ก็สามารถสร้าง link ไปยังหน้า localhost:4321/about ได้

รู้จัก Component script

Ref: https://docs.astro.build/en/core-concepts/astro-components/#the-component-script

Astro ใช้สัญลักษณ์ --- (เรียกว่า fence) ในการกำกับส่วนที่เป็น script ของ Astro component. (หน้าตาจะคล้ายๆการกำหนด properties ของ Markdown) โดยเราสามารถเขียน javascript ได้ระหว่าง fence เพื่อเป็นการกำหนด condition หรือข้อมูลก่อนการ render template ออกมาได้

โดยปกติ มักจะใช้ 2 เคสคือ

  1. กำหนดค่าเริิ่มต้นหรือ condition บางอย่างให้กับ component
  2. ดึง data ออกมาก่อนที่จะ render ตัว component ออกมา (เดี๋ยวมีิอธิบายเพิ่มเติมอีกที)

ตัวอย่างแบบง่ายๆ เช่น หากเราต้องการแสดงชื่อตัวแปร javascript เช่น name จาก javascript ลง template ของ Astro สามารถทำได้ผ่าน {name} โดยใน {} เป็นการระบุตัวแปรของ javascript ที่ได้มีการสร้างเอาไว้

---
const name = 'Mike'
---
<div>
Hello, {name}
</div>

การ import Component

Ref: https://docs.astro.build/en/tutorial/3-components/1/

เราสามารถเรียกใช้ Component อื่นๆใน Astro ได้ผ่านการ import component เข้ามาได้เช่นเดียวกัน (เหมือนกับหลายๆ Framework ที่มีในท้องตลาด) โดยการใช้คำสั่ง import ตรงๆได้เลย

สมมุติเราสร้าง component ชื่อ Navigation ไว้ใน components/Navigation.astro

<a href="/">Home</a>
<a href="/about/">About</a>

หลังจากนั้นที่ pages/index.astro ทำการ import component เข้ามา

---
import Navigation from '../components/Navigation.astro';
---
<Navigation />

ก็จะสามารถเรียกใช้ Astro component Navigation เข้ามาได้

การส่ง Props เข้า Component

Ref: https://docs.astro.build/en/core-concepts/astro-components/#component-props

เช่นเดียวกันนอกเหนือจากการ import แล้ว ยังสามารถส่ง Properties (ค่าจากภายนอก component) เข้าไปใช้งานภายใน Component ได้เช่นเดียวกัน

เช่น หากเราปรับ Navigation ให้ dynamic ตามตัวแปรที่ส่งไป แทนที่จะ fix ตามข้อมูลที่อยู่ใน Navigation ก็สามารถสร้างตัวแปรภายใน pages/index.astro และส่งเข้า component Navigation เข้าไปได้

ที่ pages/index.astro

---
import Navigation from '../components/Navigation.astro';
const pages = [
{
path: '/',
name: 'Home'
},
{
path: '/about/',
name: 'About'
}
]
---
<Navigation pages={pages} />

ที่ components/Navigation.astro

---
const { pages } = Astro.props;
---
{
pages.map((page) => (
<a href={page.path}>{page.name}</a>
))
}

ก็จะได้ผลลัพธ์ที่เหมือนกับข้างบนออกมาได้ แต่เป็นการเพิ่มความสามารถให้ dynamic ตามตัวแปรใน component หลักออกมาได้

โดยสามารถเพิ่ม condition กับตัวแปรต่างๆได้เหมือน javascript ทั่วๆไปเลย สามารถดูตัวอย่างเพิ่มเติมของ Astro ได้ที่นี่ https://docs.astro.build/en/tutorial/2-pages/3/

ทำ Dynamic route (รับตัวแปรผ่าน Route)

Ref: https://docs.astro.build/en/tutorial/5-astro-api/2/

Page component นอกเหนือจากสามารถสร้าง path ตามชื่อไฟล์ได้แล้วยังสามารถสร้าง dynamic path ผ่านชื่อไฟล์ได้เช่นกัน โดย

  • สามารถตั้งชื่อ parameter ที่ต้องการจะรับลงในชื่อไฟล์นั้นๆได้ โดยชื่อไฟล์จะต้องอยู่ภายใต้ blacket ([parameter].astro)
  • และสามารถเรียกใช้งานตัวแปรได้ผ่านคำสั่ง getStaticParam ออกมาได้

เช่น สมมุติเราต้องการสร้าง path สำหรับการดึง tag แต่ละตัวออกมา เราสร้าง path ชื่อ pages/tags/[tag].astro เราจะสามารถดึงตัวแปร tag ออกมาได้ผ่าน Astro.param เหมือนตัวอย่างนี้

---
export async function getStaticPaths() {
return [
{ params: { tag: "mike" } }
];
}
const { tag } = Astro.params
---
<div>
This is tag: {tag}
</div>

เมื่อลองเปิด path localhost:4321/tags/mike ก็จะสามารถแสดงผลลัพธ์ออกมาและเจอ path ได้ (และจะไม่เจอหากเราเปิดด้วย path อื่นที่ไม่ได้กำหนดเอาไว้)

getStaticPaths() ต้องมีเสมอเมื่อมีการใช้ parameters function นี้จำเป็นต้องมี เนื่องจาก Astro คือ static site builder ที่จะทำการ bulid page ทั้งหมดตอนจังหวะ build ออกมา (ทุกหน้าจะโดนสร้างมาทันทีตอน run คำสั่ง build) = สิ่งนี้จะทำให้ Astro รู้ว่า site ของเรามีหน้าทั้งหมดคือหน้าไหนบ้างและทำให้เราสามารถทำเว็บแบบ SSG ออกมาได้

astro-demo-04

เพิ่ม markdown ทำ content แต่ละหน้า

Ref:

มาถึงจุดเด่นของ Astro กันบ้างดีกว่า จาก Page component ที่เราพูดถึงกันไปด้านบน นอกเหนือจากไฟล์ประเภท .astro แล้ว Astro ยัง support file หลายประเภทสำหรับการเขียน Content ด้วย (ภายใต้ folder pages) ตั้งแต่

  • .astro
  • .md = Markdown
  • .mdx = Markdown แบบเสริม MDX Integration
  • .html
  • .js/.ts as API endpoints (ใช่ครับ Astro support การทำ proxy API สำหรับการดึง data เช่นกัน)

ซึ่งสำหรับคนที่เลือกใช้ Astro หลายๆคน เลือกใช้เพราะ support ภาษาอย่าง markdown ที่ช่วย support การเขียน Content ให้ง่ายขึ้นด้วยเช่นกัน

Markdown คือ markup language แบบ lightweight ที่ใช้สำหรับเก็บ text แบบมี format เอาไว้ ถูก design ไว้เพื่อให้สามารถเขียนและอ่านออกมาได้ง่ายเมื่อต้องเขียนข้อความ plain text แบบมี style ออกมา

นี่คือตัวอย่างของ markdown

# Heading Level 1
## Heading Level 2
This is a paragraph with some **bold** text and some *italic* text.
### Heading Level 3
- Bullet point 1
- Bullet point 2
- Sub bullet point
1. Numbered list item 1
2. Numbered list item 2
[This is a link](http://www.example.com)
![This is an image](https://fastly.picsum.photos/id/120/200/200.jpg?hmac=iqJko6IlBQjHPwKm31fa-KtEGqwtJfXohpfL0Y41EtQ)
`Inline code` in a sentence.

จุดเด่นใหญ่ๆจริงๆของ Markdown คือความสามารถในการแปลงภาษา Markdown ออกมาเป็น html ได้ง่าย มันจึงเป็นหนึ่งในภาษาสำหรับการเก็บ content เพื่อเตรียมแปลงเป็น style html ออกมาได้ (แม้แต่บทความของ mikelopster.dev แห่งนี้เองก็ใช้ markdown เช่นกัน)

สามารถอ่านเพิ่มเติมเกี่ยวกับการเขียน markdown ได้ที่นี่ https://www.markdownguide.org/

ทีนี้เมื่อ Astro support markdown = สามารถที่จะ render markdown ออกมาเป็น html ได้เช่นกัน

เช่น หากเราลองสร้าง folder posts และเอา markdown ด้านบนไปสร้างเป็นไฟล์ชื่อ posts/test.md

เมื่อเราลองเปิดด้วย path localhost:4321/posts/test ก็จะสามารถเปิดหน้าเว็บออกมาได้ทันที โดยไม่ต้องลงอะไรเพิ่มเติมเลย !

astro-demo-02

ดังนั้นการใช้ Astro คู่กับ Markdown จึงช่วยอำนวยความสะดวกในการทำบทความ รวมถึงการทำ Content ที่ต้องใช้ style ร่วมกันมากๆ เราสามารถเขียน global style เพื่อแต่ง markdown ทุกๆหน้าออกมาได้ และสามารถควบคุมรูปแบบการแสดงผล content ให้ทุกๆหน้าออกมาได้เหมือนๆกันได้เช่นกัน

การทำ Layout กับ Markdown

Ref: https://docs.astro.build/en/core-concepts/layouts/#markdownmdx-layouts

เนื่องจาก Markdown นั่นเป็น pattern ที่มีลักษณะเหมือนๆกันอยู่แล้วในเรื่องของการวางโครงสร้าง ดังนั้น การวาง style หรือ Layout เองก็จะคล้ายๆกันในทุกๆหน้าเช่นเดียวกัน

Astro ได้มี feature Layouts ที่สามารถกำกับ Layout ภาพรวมของทุกๆหน้า (เป็น Layout component ตัวใหญ่สุดที่คลุมเอาไว้) รวมถึงสามารถกำกับ Layout ของ Markdown ได้เช่นกัน

เช่น หากเราต้องการ Layout สำหรับการแสดงผลในหน้า markdown เราสามารถสร้างเป็น Layout component ออกมาได้ สมมุติว่าชื่อ layouts/BaseLayout.astro

---
import type { MarkdownLayoutProps } from 'astro';
type Props = MarkdownLayoutProps<{
// Define frontmatter props here
title: string;
author: string;
date: string;
}>;
const { frontmatter } = Astro.props;
---
<html>
<head>
<title>{frontmatter.title}</title>
</head>
<body>
<h1>{frontmatter.title} by {frontmatter.author}</h1>
<div class="main-container">
<slot />
</div>
<p>Written on: {frontmatter.date}</p>
</body>
</html>
<style>
.main-container {
padding: 10px;
background-color: antiquewhite;
}
</style>

เราจะสามารถ import layout นี้เข้ากับ markdown ตรงๆได้ผ่าน properties ของ Markdown ได้เลย

---
layout: ../../layouts/BaseLayout.astro
title: "Mike Test"
author: "Mikelopster "
date: "02 Jan 2024"
---
** ส่วนด้านล่างเหมือนเดิม

ก็จะได้ผลลัพธ์ออกมาเป็นการใช้ Layout ควบคุมและ markdown ก็จะไปแสดงผลตรง <slot></slot> ออกมาได้

astro-demo-03

Concept Layout นี้สามารถใช้ได้หมดทั้ง markdown และ Page component (Astro component)

ทำหน้า List blog จากข้อมูล markdown

Ref: https://docs.astro.build/en/tutorial/5-astro-api/1/

เราจะลองดึงข้อมูล Blog ทั้งหมดออกมาจากตัว markdown กัน โดย

  • ใน Astro ได้เตรียม Astro.glob ให้สามารถดึงข้อมูล Blog ออกมาได้
  • Astro.glob() คือคำสั่งสำหรับการ load local files ลงมาที่เว็บของ static ได้ ในเคสนี้เราจะทำการดึงทุก file ออกมาจาก path ของ blog (ในทีนี้คือ /posts/*.md)
  • โดยใน markdown file นั้นได้มีการ implement ตัว interface ไว้ชื่อ frontmatter (เหมือนตัว --- ใน astro component) ซึ่งตัวค่าอะไรก็ตามที่ประกาศไว้จุดเริ่มต้นของ markdown ตรง frontmatter จะสามารถเรียกใช้ผ่านตัวแปรที่คืนค่าออกมาจาก Astro.glob() ได้เลย

เช่นเคสนี้ ในตัว markdown ของ posts/test.md มี frontmatter หน้าตาแบบนี้อยู่

---
layout: ../../layouts/BaseLayout.astro
title: "Mike Test"
author: "Mikelopster"
date: "02 Jan 2024"
---
เนื้อหา markdown

เมื่อมาดึงข้อมูลที่ Astro component ก็จะสามารถดึงตัวแปรผ่าน frontmatter ออกมาได้ ผ่าน

  • post.frontmatter.title = title ที่กำหนดใน markdown (“Mike Test”)
  • post.frontmatter.author = author ที่กำหนดใน markdown (“Mikelopster”)

เป็นต้น

---
const allPosts = await Astro.glob('./posts/*.md');
---
{
allPosts.map((post) =>
<li><a href={post.url}>{post.frontmatter.title}: {post.frontmatter.author}</a></li>
)
}

เพียงเท่านี้เราก็จะสามารถ list blog ทั้งหมดออกมาได้และสามารถดึงข้อมูล Properties ของ markdown ออกมาได้

การเพิ่ม Style เข้า Astro

Ref: https://docs.astro.build/en/tutorial/2-pages/4/

เหมือนๆกับ Frontend framework ทั่วไป Astro สามารถเขียน style เข้าไปใน component ของ Astro โดยตรงได้ผ่าน tag <style></style> ใน .astro เช่นอย่างเคส Layout ด้านบนหรือเคสทั่วๆไปแบบนี้

เช่น ลองใส่ style ที่ pages/about.astro

<body>
<h1>Astro</h1>
<h1>Hello About page</h1>
</body>
<style>
h1 {
color: purple;
font-size: 4rem;
}
</style>

โดยนอกเหนือจากการใส่ style เหมือน html, css ทั่วๆไปแล้ว Astro ยัง support การใส่ style จากตัวแปร javascript ด้วยเช่นกัน โดยสามารถส่งได้ผ่าน define:vars={ {...} } กำกับคู่กับ tag <style></style> โดยใส่ตัวแปรที่ต้องการใส่เข้าไป

เช่นเคสนี้ หากเราต้องการกำกับสีผ่านตัวแปรของ javascript

  • เราจึงประกาศตัวแปร const headColor='purple' ขึ้นมาเพื่อเก็บสีม่วงเอาไว้
  • และเรียกใช้สีม่วงผ่านตัวแปร var(--headColor) ภายใน tag <style></style> ออกมาแทน
---
const headColor = 'purple';
---
<body>
<h1>Astro</h1>
<h1>Hello About page</h1>
</body>
<style define:vars={{headColor}}>
h1 {
color: var(--headColor);
font-size: 4rem;
}
</style>

ก็จะได้ผลลัพธ์ที่เหมือนกันกับเคสด้านบนออกมาได้

ดังนั้นการพิจารณาใช้สิ่งนี้จะพิจารณาอยู่บนพื้นฐานว่า

  1. เราจะกำกับ style ผ่าน CSS ล้วนๆ
  2. หรือ จะกำกับ style ผ่าน config ตัวไหนใน javascript ก็สามารถที่จะเลือกใช้วิธีส่งตัวแปรแทนได้

รวมถึง tailwind เองก็ Support Astro เช่นกัน สามารถใช้ร่วมกันได้ (สำหรับคนที่ถนัด utility class style) https://tailwindcss.com/docs/guides/astro

จริงๆมีเรื่องอื่นๆเพิ่มเติมสามารถอ่านผ่าน Docs ของ Astro ได้ มันก็จะมีเพิ่มเติมตั้งแต่

  • การทำ global style = style ให้กับทุกๆ component (เนื่องจาก default ของ Astro เป็น scoped style)
  • การประยุกต์ใช้ร่วมกันระหว่าง Props กับ Style https://docs.astro.build/en/guides/styling/

ส่งตัวแปรจาก Server เข้า Component

Ref: https://docs.astro.build/en/guides/data-fetching/#fetch-in-astro

นอกเหนือจาก static content อย่าง markdown แล้ว Astro ยัง support การทำ Dynamic content เช่นเดียวกัน

  • อย่างแรกสุด สามารถส่งตัวแปรจาก javascript มาแสดงผลที่ Component ได้ (เหมือนตัวอย่างด้านบน)
  • อีกอย่างคือสามารถดึงข้อมูลจาก API มาไว้ก่อนและนำมาแสดงผลที่ Component ออกมาได้ (เป็นการดึงข้อมูลจากฝั่ง Server และส่งมาแสดงผลที่ Component ออกมา)

เช่นเคสนี้ เราจะดึงข้อมูล Blog จากแหล่งอื่นมาแสดงผ่าน Mock API (Endpoint ที่ได้เตรียมไว้สำหรับการดึงข้อมูล ex. https://<mock-api-id>.mockapi.io/blogs) หน้าตาของผลลัพธ์ API จะเป็นประมาณนี้

[
{
"name": "Eva Wieva elfientheiser1",
"content": "awdawdawdawd",
"imageUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/735.jpg",
"author": "Winifred Dickinson",
"description": "Reiciendis itaque aliquid amet. Mollitia vitae eum deleniti sequi ipsa. Perspiciatis error doloribus provident amet tenetur similique rerum. Facere doloremque cupiditate debitis.",
"id": "1",
"createdAt": "2023-12-21T10:38:23.703Z",
"avatar": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/496.jpg"
},
/* ... */
]

ดังนั้น เมื่อมาใช้กับ Astro component เราจะต้องดึงข้อมูลใส่ตัวแปรหนึ่งไว้ก่อน (สมมุติชื่อ posts) และนำมาแสดงผลผ่านตัวแปรนั้นออกมาได้ เช่น เคสนี้เราจะลองเพิ่มเติมไว้ที่ pages/external.astro ออกมา

---
const response = await fetch('https://<mock-api-id>.mockapi.io/blogs');
const posts = await response.json();
---
<div>
{
posts.map(post => (
<div class="flex">
<img width="50px" src={post.imageUrl} />
<div>{post.name}</div>
</div>
))
}
</div>
<style>
.flex {
display: flex;
align-items: center;
gap: 10px;
margin: 2px 0;
}
</style>

ผลลัพธ์ก็จะได้ออกมาหน้าตาประมาณนี้

astro-demo-05

การเพิ่ม script javascript สำหรับฝั่ง client

Ref: https://docs.astro.build/en/tutorial/3-components/4/

สำหรับ Javascript ของฝั่ง Client นั้น Astro จะใช้วิธีการ handle case แบบทั่วๆไปคือ ใส่ tag <script> เหมือน html และทำการ access html ผ่าน javascript ตรงๆได้เลย เช่นแบบนี้

<div>
<button id="testButton">Test button</button>
<script>
const testBtn = document.getElementById('testButton')
testBtn.addEventListener('click', () => {
console.log('test button')
})
</script>
</div>

หากใครจะใช้ library Frontend framework ตัวอื่นๆเช่น React, Vue ก็สามารถ import มาใช้งานตรงๆได้เช่นเดียวกัน ดูตัวอย่างเพิ่มเติมในเอกสารของ Astro ได้ https://docs.astro.build/en/guides/client-side-scripts/#client-side-scripts

Shortcut ด้วยการหา theme

Ref: https://astro.build/themes/

astro-theme

สำหรับใครที่อยากเริ่มต้นแบบรวดเร็ว ใน Astro เองมี Theme Marketplace อยู่ ซึ่งสามารถ clone มาลองใช้งานดูก่อนได้ สามารถทำให้เราเห็นภาพรวมของหลายๆ project ได้ดีขึ้นเช่นกันว่าปกติวาง project structure กันยังไงบ้าง

  • mikelopster.dev ใช้ cactus เป็น based หลัก (ที่กำลังค่อยๆทยอยเอา style เข้า-ออก อยู่)

การใช้ร่วมกับสิ่งอื่นๆ

Related Post

Share on social media