Files
opencode-skill/skills/website-creator/SKILL.md
Kunthawat Greethong a29b7af4b8 feat: update website-creator to Plan-First + Creative Design workflow
- Add Phase 1: Context Gathering with creative brief questions
- Add Phase 2: Creative Design (mandatory - multiple directions)
- Add Phase 3: Master Plan before execution
- Add APPROVAL GATE - wait for user approve before executing
- Update questions.md with emotional/target audience questions
- Remove Astro DB references from welcome.mdx and index.astro
- Focus on unique design, not generic templates
2026-04-22 09:31:54 +07:00

36 KiB
Raw Blame History

name, description, tags, category, related_skills
name description tags category related_skills
website-creator สร้างเว็บไซต์เต็มรูปแบบด้วย Astro + Tina CMS พร้อม Workflow สำหรับเว็บใหม่และ Migration ครอบคลุม Design System, Content Collections, Auth, SEO, PDPA Compliance และ Deploy
astro
website
website-development
website-creation
migration
tailwindcss
thai
pdpa
seo
tina-cms
image-generation
picture-it
software-development
spec-driven-development
frontend-ui-engineering
api-and-interface-design
code-review-and-quality
performance-optimization
browser-testing-with-devtools
shipping-and-launch

Website Creator Skill

สร้างเว็บไซต์เต็มรูปแบบด้วย Astro + Tina CMS

Architecture

Astro + Tina CMS Stack:

  • Astro 6.x — Static site generator ที่เร็วมาก รองรับ React/Vue/Svelte components
  • Tina CMS — Self-hosted Git-based CMS สำหรับ visual content editing
  • Tailwind CSS 4.x — ใช้ @tailwindcss/vite plugin
  • External Consent System — Consent script จาก consent.moreminimore.com

Pattern อ้างอิง: ใช้ template ที่มีอยู่แล้ว: templates/astro-tina-starter/

Astro Project Structure

src/
├── components/           # Astro/React components
├── content/              # Tina CMS content (MDX)
│   ├── posts/           # Blog posts
│   ├── pages/           # Static pages
│   └── settings/        # Site settings (JSON)
├── layouts/
│   └── Layout.astro     # Main layout
├── pages/
│   ├── index.astro      # Home page
│   └── [...slug].astro  # Dynamic pages
├── styles/
│   └── global.css       # Tailwind v4 + @theme
└── env.d.ts

.tina/                   # Tina CMS configuration
├── config.ts            # Tina config
└── schema.ts            # Content schema

astro.config.mjs         # Astro + Tailwind v4 + Tina
package.json

Static vs SSR

  • Static (default): Pre-built HTML + รันบน CDN
  • SSR/Hybrid: ใช้เมื่อต้องการ API routes หรือ dynamic content
  • Hybrid: บางหน้า static บางหน้า dynamic

สำหรับ Easypanel: ใช้ output: 'static' หรือ output: 'hybrid' (ถ้าต้องการ API routes)

Critical Configuration Rules

1. astro.config.mjs (Tailwind v4 + Tina)

import { defineConfig } from 'astro/config'
import tailwindcss from '@tailwindcss/vite'
import tina from 'tinacms'

export default defineConfig({
  integrations: [
    tina({
      enabled: !!process.env.TINA_TOKEN,
      sidebar: { partials: [] },
    }),
  ],
  vite: {
    plugins: [tailwindcss()],  // Tailwind v4 ใช้ @tailwindcss/vite
  },
  output: 'static',  // หรือ 'hybrid' ถ้าต้องการ API routes
})

2. Required Dependencies

{
  "dependencies": {
    "astro": "^6.1.7",
    "@tinacms/cli": "^2.1.0",
    "tinacms": "^2.2.0"
  },
  "devDependencies": {
    "@tailwindcss/vite": "^4.0.0",
    "tailwindcss": "^4.0.0",
    "@astrojs/mdx": "^4.0.0",
    "typescript": "^5.6.0"
  }
}

CRITICAL: Tailwind v4 ใช้ @tailwindcss/vite plugin ไม่ใช่ @astrojs/tailwind

3. Tailwind v4 Configuration

Tailwind v4 ไม่มี tailwind.config.js — ใช้ CSS @theme block แทน:

/* src/styles/global.css */
@import "tailwindcss";

@theme {
  /* Fonts */
  --font-sans: "Inter", "Noto Sans Thai", system-ui, sans-serif;
  
  /* Colors */
  --color-primary-50: #f8fafc;
  --color-primary-900: #0f172a;
  --color-accent-500: #3b82f6;
  
  /* Border Radius */
  --radius-sm: 0.25rem;
  --radius-lg: 0.75rem;
  --radius-xl: 1rem;
}

4. Tina CMS Schema

// .tina/schema.ts
import { defineSchema } from 'tinacms'

export const schema = defineSchema({
  collections: [
    {
      name: 'post',
      label: 'Posts',
      path: 'src/content/posts',
      format: 'mdx',
      fields: [
        { type: 'string', name: 'title', label: 'Title', required: true },
        { type: 'string', name: 'slug', label: 'Slug', required: true },
        { type: 'datetime', name: 'publishedAt', label: 'Published At' },
        { type: 'rich-text', name: 'body', label: 'Body', isBody: true },
      ],
    },
    {
      name: 'page',
      label: 'Pages',
      path: 'src/content/pages',
      format: 'mdx',
      fields: [
        { type: 'string', name: 'title', label: 'Title', required: true },
        { type: 'string', name: 'slug', label: 'Slug', required: true },
        { type: 'rich-text', name: 'body', label: 'Body', isBody: true },
      ],
    },
  ],
})

Workflow A: สร้างเว็บใหม่

⚠️ สำคัญ: ต้องวางแผนก่อน + รอ approve ก่อนทำงานเสมอ

ขั้นตอน: Context → Design → Plan → Approve → Execute


Phase 1: Context Gathering (ถามให้ครบ)

ใช้ references/questions.md เป็นแนวทาง แต่ต้องถามให้ลึกกว่า surface level:

1.1 ข้อมูลพื้นฐาน

1. ชื่อเว็บไซต์/บริษัท?
2. ทำอะไร? (ขายอะไร/ให้บริการอะไร)
3. กลุ่มเป้าหมายคือใคร?
4. มีเว็บอยู่แล้วหรือยัง?

1.2 Brand Context (ทำให้ต่างจากคนอื่น)

5. ทำไมลูกค้าควรเลือกคุณ ไม่ใช่คู่แข่ง?
6. มี brand story หรือ positioning อะไรที่ต้องสื่อสาร?
7. มี tone of voice หรือ personality อย่างไร? (เช่น: friendly, professional, bold, playful)

1.3 Design Context

8. มี brand guidelines/logo file ไหม?
9. มี reference sites ที่ชอบ/ไม่ชอบบ้างไหม? (ส่งลิงก์มาได้)
10. มีสีที่ต้องใช้/ห้ามใช้บ้างไหม?

1.4 Technical Context

11. ต้องการหน้าอะไรบ้าง? (sitemap)
12. มี SMTP/email สำหรับส่งเมลไหม?
13. มี tracking tools ต้องติดตั้งไหม? (GA4, Facebook Pixel, etc.)
14. มี DPO หรือยัง? (สำหรับ PDPA)

Phase 2: Creative Design (บังคับต้องทำ)

เรียก skills: ckm:design + ui-ux-pro-max + frontend-ui-engineering

2.1 สร้าง Creative Brief

ก่อนสร้าง design ต้องมี creative brief ที่ชัดเจน:

# Creative Brief

## Brand Essence
- ชื่อ/บริษัท: [ชื่อ]
- สิ่งที่ทำ: [บริการ/สินค้า]
- ทำไมต่าง: [unique selling point]

## Target Emotion
- ต้องการให้คนเข้าเว็บแล้วรู้สึก: [เช่น มั่นใจ, สบายใจ, ตื่นเต้น, ไว้วางใจ]

## Design Direction
- ห้ามใช้: [สี/รูปแบบที่ไม่ชอบ]
- อาจใช้: [สี/รูปแบบที่ชอบ]
- References: [ลิงก์ที่ชอบ/ไม่ชอบ]

2.2 สร้าง 2-3 Creative Directions ที่ต่างกันจริงๆ

ใช้ ckm:design + ui-ux-pro-max สร้าง options ที่แตกต่างกัน:

Direction A: "[Name]"
- Concept: [แนวคิดหลัก]
- Visual Style: [ลักษณะ visuals]
- Color Palette: [โทนสี]
- Typography: [แบบอักษร]
- Layout Character: [โครงสร้าง layout ที่เป็นเอกลักษณ์]

Direction B: "[Name]"
- Concept: [แนวคิดหลัก - ต่างจาก A]
- Visual Style: [ลักษณะ visuals - ต่างจาก A]
- Color Palette: [โทนสี - ต่างจาก A]
- Typography: [แบบอักษร - ต่างจาก A]
- Layout Character: [โครงสร้าง layout - ต่างจาก A]

2.3 Present + Wait for Selection

นำเสนอ directions ทั้งหมด แล้วรอ user เลือก


Phase 3: Master Plan (วางแผนทั้งหมด)

เรียก skill: spec-driven-development

สร้าง master plan ที่รวมทุกอย่าง:

# Master Plan: [ชื่อเว็บ]

## Selected Design Direction
[Direction ที่ user เลือกพร้อม rationale]

## Sitemap
/
├── home
├── about
├── services
├── contact
└── ...

## Design System
- Colors: [hex codes]
- Typography: [fonts + weights]
- Components: [list]
- Layout Patterns: [descriptions]

## Content Structure (Tina CMS)
- Collections: [posts, pages, etc.]
- Fields: [schema]

## Technical Stack
- Framework: Astro 6
- CMS: Tina CMS
- Styling: Tailwind CSS v4
- Consent: ConsentOS

## Tracking Scripts
- Analytics: [tools]
- Marketing: [tools]

## PDPA Compliance
- Privacy Policy
- Terms of Service
- ConsentOS Integration

## Development Phases
1. [Phase 1: Setup + Design Foundation]
2. [Phase 2: Build Pages]
3. [Phase 3: Content + QA]
4. [Phase 4: Deploy]

## Timeline
- Phase 1: X days
- Phase 2: X days
- Phase 3: X days

⏸️ APPROVAL GATE

หยุดที่นี่ - รอ APPROVE ก่อนทำงาน

แสดง:

  1. Design direction ที่เลือก (screenshot/mockup)
  2. Sitemap ที่จะสร้าง
  3. Tech stack summary
  4. Timeline estimate

รอ user พิมพ์ "approve" หรือ "เริ่มได้" ก่อนไปต่อ


Phase 4: Execution (เริ่มทำหลัง APPROVE)

หลังได้รับ approve แล้ว ทำตามแผนที่ approve โดยไม่ต้องถามต่อ

Phase 4.1: Setup + Design Foundation

bash skills/website-creator/scripts/new-project.sh my-website

จากนั้น implement design system ที่ approve:

  • Colors ใน Tailwind theme
  • Typography
  • Base components
  • Layout patterns

Phase 4.2: Build Pages

Implement ทุก pages ตาม sitemap ที่ approve แล้ว

Phase 4.3: Content + Integration

  • Tina CMS setup + content schema
  • Legal pages (Privacy Policy, ToS)
  • ConsentOS integration
  • Tracking scripts

Phase 4.4: QA + Deploy

ตาม Step 9-10 ด้านล่าง


Step 9: Preview + QA

npm run dev

ก่อน QA — เรียก skills ตามลำดับ:

  1. code-review-and-quality — Full multi-axis code review ก่อน delivery
  2. performance-optimization — Performance audit + fixes
  3. browser-testing-with-devtools — ทดสอบใน real browser

จากนั้นเรียก dogfood สำหรับ exploratory QA:

/skill dogfood
"ทดสอบ user journey:
 1. ดู home page → คลิก services
 2. ดู about us
 3. กรอก contact form
 4. ทดสอบ consent popup (ConsentOS)
 5. ตรวจ PDPA compliance (privacy policy, terms)
 6. ตรวจ mobile responsive
 7. ตรวจ SEO meta tags ทุกหน้า"

ให้ user ตรวจสอบ → รอ feedback → แก้ไข → รอ approve


Step 10: Deploy

เรียก skill: easypanel-deploy เมื่อ user ขอ

/skill easypanel-deploy
"deploy ไปยัง easypanel server
 server: openclaw-vps
 project: my-website
 domain: example.com
 git repo: https://github.com/user/my-website"

Step 4: Setup Astro + Tina CMS Project

ใช้ script ที่มีอยู่แล้ว:

# สร้าง project ใหม่จาก template
bash skills/website-creator/scripts/new-project.sh my-website

# หรือระบุ path
bash skills/website-creator/scripts/new-project.sh my-website /path/to/projects/

Script ทำอะไร:

  1. Copy template templates/astro-tina-starter/
  2. เพิ่ม PDPA consent system
  3. Copy legal templates (privacy policy, terms)
  4. ติดตั้ง dependencies
  5. สร้าง .env file
  6. Initialize git

เปิด browser:


Step 5: พัฒนา Components + Pages

เรียก skills: spec-driven-development + api-and-interface-design + ckm:design + ckm:ui-styling + frontend-ui-engineering

สร้างตาม sitemap ที่วางแผนไว้:

  • FrontendLayout, Navigation, Footer
  • Pages (Home, About, Services, Contact)
  • Blog listing + detail pages
  • Forms (Contact form ส่ง email จริง)

สำคัญ — แยก Design Layer กับ Content Layer:

Design skill (ui-ux-pro-max) ออกแบบ หน้าตา + layout + animation — ไม่ใช่ content structure Tina CMS เก็บ เนื้อหา (ข้อความ, format, links, images) — ไม่ใช่ layout

ทั้งสองอยู่คนละ layer กัน → ต้องแยกทำ แล้วมารวมกันตอน integrate


Step 5b: สร้างภาพประกอบด้วย picture-it

เรียก skill: picture-it

สำหรับทุก page/section ที่ต้องการ hero image, illustration หรือภาพประกอบ:

วิธีใช้:

# Load credentials ก่อน
set -a && source ~/.config/opencode/.env && set +a
export PATH="/home/kunthawat/snap/bun-js/87/.bun/bin:$PATH"

# ตรวจสอบ Thai font patch
bun ~/.hermes/skills/website-creator/creative/picture-it/scripts/thai-font-patch.ts --force

Workflow สร้างภาพประกอบเว็บ:

Use Case Pipeline ค่าใช้จ่าย
Hero background generate flux-schnell + text (Thai) + grade cinematic + vignette ~$0.003
Service illustration generate flux-schnell + remove-bg (ถ้ามี product) + compose ~$0.01
Blog hero generate flux-schnell + edit seedream (place logo) + grade ~$0.043
Social/OG image generate flux-schnell + text + grade ~$0.003
Team/About photo generate flux-schnell → realistic headshot style ~$0.003

ขนาดภาพแนะนำ:

Purpose Size
Hero banner 1200×630 หรือ 1920×1080
Blog hero 1200×630
OG Image (social share) 1200×630
Service card 800×600
Team member 400×400 (circle crop)
Logo (ในภาพ) 200×200 หรือเล็กกว่า

Workflow ตัวอย่าง — Hero Section:

# 1. Generate background
picture-it generate \
  --prompt "modern tech workspace, clean minimal, yellow #fed400 accent lighting" \
  --size 1200x630 \
  --model flux-schnell \
  -o hero-bg.png

# 2. เพิ่ม Thai text
picture-it text \
  -i hero-bg.png \
  --title "บริการรับทำเว็บไซต์ SEO" \
  --font "Kanit" \
  --font-size 48 \
  -o hero-texted.png

# 3. Color grade
picture-it grade -i hero-texted.png --name cinematic -o hero-final.png

การบันทึกภาพไว้ใน project:

src/
├── components/
│   └── Hero.astro          # Hero component
└── assets/
    ├── heroes/             # Hero images
    ├── services/           # Service illustrations
    ├── blog/               # Blog heroes
    └── og/                 # Open Graph images

Step 5c: Design + Tina Content Integration

Design layer กับ Content layer แยกกัน — ค่อยรวมตอน build

สิ่งที่ต้องเข้าใจ

┌─────────────────────────────────────────────────────────┐
│  ui-ux-pro-max / ckm:design — Design Layer              │
│  • Component structure (Hero, Card, Navbar)              │
│  • Color tokens, typography, spacing                      │
│  • Animation specs (150-300ms, ease-out)                 │
│  • Layout grid, responsive breakpoints                   │
│  • Interaction states (hover, press, disabled)           │
│  Output: Astro + Tailwind code (component skeleton)      │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  Tina CMS — Content Layer                                │
│  • ข้อความ + format (bold, italic, link)               │
│  • Headings (H1-H6)                                     │
│  • Lists, blockquotes, code blocks                       │
│  • Images, links                                        │
│  Output: MDX files (เนื้อหา)                             │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  Integration — ครอบ Tina content ด้วย Design            │
│  • Design component ครอบ MDX output                     │
│  • Animation class ที่ wrapper element                   │
│  • Design tokens apply ผ่าน Tailwind prose             │
└─────────────────────────────────────────────────────────┘

ขั้นตอนที่ถูกต้อง

[1] Design Phase
    ui-ux-pro-max → Component structure, tokens, animations
    Output: Component skeleton (ไม่มี content)
         ↓
[2] Tina Phase
    สร้าง Content Collections + MDX files
    Output: Content structure ใน Tina (src/content/)
         ↓
[3] Content Phase
    พิมพ์ content ใน Tina Admin (/admin)
    Output: MDX files
         ↓
[4] Integration Phase
    ครอบ Tina content ด้วย Design components

ตัวอย่าง: Page Structure (Design Output)

Design skill อาจให้ component แบบนี้:

---
// ❌ สิ่งที่ design skill อาจให้มา — hardcode content
---

<div class="hero-section">
  <h1>Welcome to Our Site</h1>  <!-- hardcode -->
  <p class="hero-desc">Amazing content here...</p>  <!-- hardcode -->
</div>

ต้องแปลงเป็น:

---
// ✅ ครอบ Tina content ด้วย design component
import { Container, Heading, Prose } from '@/components/ui';

interface Props {
  title: string;
  body: string;  // จาก MDX frontmatter หรือ Tina query
}

const { title, body } = Astro.props;
---

<Container class="py-20">
  <Heading level={1} class="text-5xl font-bold mb-6">{title}</Heading>
  {body && (
    <Prose>
      <slot />  <!-- MDX content จะมาอยู่ตรงนี้ -->
    </Prose>
  )}
</Container>

Tina Content Collections

กำหนดว่า content แต่ส่วนเก็บใน collection ไหน:

// .tina/schema.ts
const schema = defineSchema({
  collections: [
    {
      name: 'post',
      label: 'Posts',
      path: 'src/content/posts',
      fields: [
        { type: 'string', name: 'title', label: 'Title', required: true },
        { type: 'string', name: 'slug', label: 'Slug', required: true },
        { type: 'string', name: 'description', label: 'Description' },
        { type: 'datetime', name: 'publishedAt', label: 'Published At' },
        { type: 'rich-text', name: 'body', label: 'Body', isBody: true },
      ],
    },
    {
      name: 'page',
      label: 'Pages',
      path: 'src/content/pages',
      fields: [
        { type: 'string', name: 'title', label: 'Title', required: true },
        { type: 'string', name: 'slug', label: 'Slug', required: true },
        { type: 'rich-text', name: 'body', label: 'Body', isBody: true },
      ],
    },
    {
      name: 'settings',
      label: 'Settings',
      path: 'src/content/settings',
      format: 'json',
      fields: [
        { type: 'string', name: 'siteName', label: 'Site Name' },
        { type: 'string', name: 'siteDescription', label: 'Description' },
      ],
    },
  ],
})

วิธี Integrate: Design Components + Tina Content

---
// src/pages/blog/[slug].astro
import Layout from '@/layouts/Layout.astro';
import { Container, Heading, Prose } from '@/components/ui';

// Astro ดึง content จาก MDX files
const { slug } = Astro.params;

// ด้วย Astro content collections
const { post } = Astro.props;
---

<Layout title={post.data.title} description={post.data.description}>
  <Container class="py-20">
    <Heading level={1} class="text-5xl font-bold mb-6">
      {post.data.title}
    </Heading>
    
    {post.data.description && (
      <p class="text-xl text-gray-600 mb-8">{post.data.description}</p>
    )}
    
    <Prose>
      <!-- MDX content จะ render ตรงนี้ -->
      <slot />
    </Prose>
  </Container>
</Layout>

Step 7: PDPA Compliance

ใช้ templates ที่มีอยู่แล้ว:

  1. Privacy Policy — ใช้ templates/privacy-policy.md

    • ภาษากฎหมาย PDPA ครบถ้วน
    • แทนที่ placeholders ด้วยข้อมูลจริง
  2. Terms of Service — ใช้ templates/terms-of-service.md

  3. ConsentOS + Tracking Scripts — ใช้ src/components/TrackingScripts.astro

Template มี TrackingScripts.astro ที่รองรับ:

Category Script ENV Variable
Analytics Google Analytics 4 PUBLIC_GA4_ID
Analytics Google Tag Manager PUBLIC_GTM_ID
Analytics Umami PUBLIC_UMAMI_URL, PUBLIC_UMAMI_WEBSITE_ID
Analytics Microsoft Clarity PUBLIC_CLARITY_ID
Marketing Facebook Pixel PUBLIC_FB_PIXEL_ID
Marketing Google Ads PUBLIC_GOOGLE_ADS_ID
Marketing TikTok Pixel PUBLIC_TIKTOK_PIXEL_ID
Marketing LINE Channel Tag PUBLIC_LINE_CHANNEL_ID

Environment Variables:

# ConsentOS
PUBLIC_CONSENT_SITE_ID=your-consent-site-id
PUBLIC_CONSENT_API_BASE=https://consent.moreminimore.com

# Analytics
PUBLIC_GA4_ID=G-XXXXXXXXXX
PUBLIC_GTM_ID=GTM-XXXXXXX
PUBLIC_UMAMI_URL=https://umami.example.com
PUBLIC_UMAMI_WEBSITE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
PUBLIC_CLARITY_ID=xxxxxxxxxx

# Marketing
PUBLIC_FB_PIXEL_ID=123456789
PUBLIC_GOOGLE_ADS_ID=AW-123456789
PUBLIC_TIKTOK_PIXEL_ID=XXXXXXXX
PUBLIC_LINE_CHANNEL_ID=1234567890

Tracking Flow:

TrackingScripts.astro (data-consent-category attributes)
        ↓
ConsentOS consent-loader.js (scan + auto-block)
        ↓
Scripts execute only after user consent

Consent Categories:

  • Analytics — GA4, GTM, Umami, Clarity
  • Marketing — Facebook Pixel, TikTok, LINE, Google Ads

Right to be Forgotten:

  • ConsentOS มี API สำหรับลบข้อมูล user

Step 8: SEO Setup

เรียก skills: seo-analyzers + seo-geo + seo-multi-channel

  1. Meta tags ทุกหน้า — ใช้ frontmatter จาก MDX หรือ static
  2. sitemap.xml — Astro ใช้ @astrojs/sitemap
  3. robots.txt
  4. Open Graph imagesใช้ picture-it สร้าง OG image template ที่ consistent
  5. JSON-LD structured data
  6. Thai language optimization
# ติดตั้ง sitemap
npx astro add sitemap
// astro.config.mjs
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://example.com',
  integrations: [sitemap(), tina()],
});

Step 9: Preview + QA

npm run dev

ก่อน QA — เรียก skills ตามลำดับ:

  1. code-review-and-quality — Full multi-axis code review ก่อน delivery
  2. performance-optimization — Performance audit + fixes
  3. browser-testing-with-devtools — ทดสอบใน real browser

จากนั้นเรียก dogfood สำหรับ exploratory QA:

/skill dogfood
"ทดสอบ user journey:
 1. ดู home page → คลิก services
 2. ดู about us
 3. กรอก contact form
 4. ทดสอบ consent popup (ConsentOS)
 5. ตรวจ PDPA compliance (privacy policy, terms)
 6. ตรวจ mobile responsive
 7. ตรวจ SEO meta tags ทุกหน้า"

ให้ user ตรวจสอบ → รอ feedback → แก้ไข → รอ approve


Step 10: Deploy

เรียก skill: easypanel-deploy

/skill easypanel-deploy
"deploy ไปยัง easypanel server
 server: openclaw-vps
 project: my-website
 domain: example.com
 git repo: https://github.com/user/my-website"

Workflow B: ปรับปรุงเว็บที่มีอยู่แล้ว (Existing Repo)

ความหมายของ "Existing Repo"

Repo ที่มีโครงสร้าง Astro + Tina แล้ว แต่ยังไม่สมบูรณ์ — เช่น:

  • มี starter template แต่ไม่มี content
  • มี design tokens แล้วแต่ยังไม่มี pages
  • มีบางหน้าแต่ต้องการปรับปรุงเนื้อหา/design

ไม่ใช่ 新规 creation — มี codebase อยู่แล้ว ปรับในที่เดิม


ขั้นตอน

[1] ตรวจสอบ repo ที่มี (terminal/find ดูโครงสร้าง)
        │
[2] สำรวจ: astro.config.mjs, components, pages, design tokens
        │
[3] สำรวจ content ที่มี (Posts, Pages จากเว็บเดิม) → วางแผน Migration
        │
[4] Migrate content เข้า Tina CMS
        │
[5] ตรวจสอบ /admin ว่าเห็น Posts + Pages พร้อมแก้ไขได้
        │
[6] Integrate: อัปเดต Pages ให้อ่านจาก Tina แทน hardcode
        │   (ดู **Design + Tina Integration** ด้านบน)
        │
[7] สรุปสิ่งที่มี vs สิ่งที่ขาด → แผน Sitemap
        │
[8] ถามคำถามที่ขาด (content, portfolio, pricing, dark/light)
        │
[9] รอ approve
        ↓
จากนั้น → Workflow A Step 3 เป็นต้นไป (พัฒนา Components + Pages)

Migration: Next.js + Payload → Astro + Tina

ใช้ script ที่มีอยู่แล้ว:

# Migrate existing website ไป Astro + Tina
bash skills/website-creator/scripts/migrate-tina.sh /path/to/existing-site /path/to/migrated-site

Script ทำอะไร:

  1. Detect source technology (Astro, Next.js, Remix, etc.)
  2. Analyze source content
  3. Copy Astro+Tina template
  4. Migrate content (MD/MDX files)
  5. Add PDPA consent system
  6. Create Tina schema
  7. Generate migration report

Content Migration Checklist

จาก Payload ไป Tina
payload.find() Astro content collections
RichText component MDX files
payload.config.ts collections .tina/schema.ts collections
MongoDB/PostgreSQL ConsentOS (external)
/admin /admin (Tina visual editor)
Payload Auth Tina Auth (optional)

Astro Content Collections

Astro ใช้ content collections สำหรับ type-safe content management:

สร้าง Collection

// src/content/config.ts
import { defineCollection, z } from 'astro:content';

const postsCollection = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    description: z.string().optional(),
    publishedAt: z.date().optional(),
    author: z.string().optional(),
    image: z.string().optional(),
  }),
});

const pagesCollection = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    description: z.string().optional(),
  }),
});

export const collections = {
  posts: postsCollection,
  pages: pagesCollection,
};

ใช้ Collection

---
// src/pages/blog/[slug].astro
import { getCollection } from 'astro:content';

export async function getStaticPaths() {
  const posts = await getCollection('posts');
  return posts.map((post) => ({
    params: { slug: post.slug },
    props: { post },
  }));
}

const { post } = Astro.props;
const { Content } = await post.render();
---

<article>
  <h1>{post.data.title}</h1>
  <Content />
</article>

Tina CMS Integration

Local Development

npm run dev

Tina จะ available ที่ http://localhost:4321/admin หรือ http://0.0.0.0:4321/admin

Production Setup

# รัน script สำหรับติดตั้ง Tina backend
bash scripts/install-tina-backend.sh

ต้องมี:

  • TINA_TOKEN — Production authentication token
  • TINA_CLIENT_ID — Tina client ID

Tina Schema Best Practices

// .tina/schema.ts
const schema = defineSchema({
  collections: [
    {
      name: 'post',
      label: 'Blog Posts',
      path: 'src/content/posts',
      fields: [
        {
          type: 'string',
          name: 'title',
          label: 'Title',
          isTitle: true,  // ใช้เป็น title ใน admin UI
          required: true,
        },
        {
          type: 'string',
          name: 'slug',
          label: 'URL Slug',
          required: true,
        },
        {
          type: 'datetime',
          name: 'publishedAt',
          label: 'Publish Date',
        },
        {
          type: 'rich-text',
          name: 'body',
          label: 'Content',
          isBody: true,  // เป็น body หลัก
        },
      ],
    },
  ],
})

Templates

Astro Tina Starter (templates/astro-tina-starter/)

Base template ที่รวมทุกอย่างพร้อม:

astro-tina-starter/
├── .tina/
│   ├── config.ts       # Tina CMS configuration
│   └── schema.ts       # Content schema definitions
├── src/
│   ├── styles/
│   │   └── global.css  # Tailwind v4 styles + @theme
│   ├── layouts/
│   │   └── Layout.astro
│   ├── pages/
│   │   └── index.astro
│   ├── components/
│   │   └── Header.astro
│   └── content/
│       ├── config.ts   # Astro content collections
│       ├── posts/       # Blog posts (MDX)
│       ├── pages/       # Static pages (MDX)
│       └── settings/    # Site settings (JSON)
├── public/
│   └── favicon.svg
├── Dockerfile
├── astro.config.mjs
├── tsconfig.json
└── package.json

Features ที่มี:

  • Astro 6.1.7 + Tina CMS 2.x
  • Tailwind CSS 4.x with @tailwindcss/vite
  • Thai language support
  • Docker-ready
  • External consent system integration

Docker

Development

docker compose up -d

Production (Multi-stage Dockerfile)

FROM node:22-alpine AS deps
RUN corepack enable && corepack prepare pnpm@9.0.0 --activate
WORKDIR /app
COPY package.json pnpm-lock.yaml* ./
RUN pnpm install --frozen-lockfile

FROM deps AS builder
COPY . .
RUN pnpm build

FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
RUN adduser --system --uid 1001 astro
USER astro
EXPOSE 8080
CMD ["node", "dist/server/entry.mjs"]

Build command:

npm run build

Sub-skill Routing

ขั้นตอน Sub-skill รายละเอียด
ตลอด workflow spec-driven-development เขียน spec ก่อน implement ทุกครั้ง
Design Framework ckm:design Brand, tokens, design system
Design Framework frontend-ui-engineering UI component architecture, patterns
UI Components ckm:ui-styling shadcn/ui, Tailwind CSS
UI/UX Design ui-ux-pro-max Wireframes, mockups, 50+ design patterns
Brand Identity brand Logo, colors, typography, voice
Banner/Hero Images banner-design Social, ads, web heroes
Develop Components + Pages api-and-interface-design API design, component interfaces
Before QA code-review-and-quality Full multi-axis code review
Before QA performance-optimization Performance audit + fixes
QA Testing browser-testing-with-devtools Real browser testing
QA Testing dogfood Exploratory QA of web app
SEO Planning seo-context Per-project SEO context
SEO Audit seo-analyzers Thai language SEO analysis
GEO (AI Search) seo-geo AI Overviews, llms.txt, crawler
Multi-channel Content seo-multi-channel Facebook, LinkedIn, blog content
Deploy easypanel-deploy Easypanel hosting
Design + Tina Integration frontend-ui-engineering แยก design layer กับ content layer

Troubleshooting

Build fails: "Cannot find module '@tailwindcss/vite'"

Error: Cannot find module '@tailwindcss/vite'

ทางแก้:

# ติดตั้ง @tailwindcss/vite
npm install -D @tailwindcss/vite

# หรือถ้าใช้ Tailwind v3 syntax อยู่ → ต้องเปลี่ยนเป็น v4
# ใน global.css:
@import "tailwindcss";  # ไม่ใช่ @tailwind base; @tailwind components; @tailwind utilities;

Tina Admin not loading

อาการ: /admin แสดง blank page หรือ error

ทางแก้:

  1. ตรวจสอบว่า Tina config ถูกต้อง:
// astro.config.mjs
import tina from 'tinacms';

export default defineConfig({
  integrations: [tina()],
});
  1. ตรวจสอบว่า .tina/schema.ts มีอยู่

  2. ลองรัน npm run dev ใหม่

Port already in use

Error: Port 4321 is already in use

ทางแก้:

# หา process ที่ใช้ port
lsof -i :4321

# kill process
kill <PID>

# หรือรัน port อื่น
npm run dev -- --port 4322

MDX content not rendering

อาการ: MDX files ไม่แสดง content

ทางแก้:

---
// ต้องใช้ .render() เพื่อดึง Content component
const { Content } = await post.render();
---

<Content />

Key Principles

  1. Plan-First Approach

    • แสดงแผนก่อนลงมือเสมอ
    • รอ user approve ก่อน
  2. Astro Latest

    • ใช้ Astro 6.x เวอร์ชั่นล่าสุด
    • Tina CMS สำหรับ content management
  3. Thai-First

    • ภาษาไทยเป็นหลัก
    • Thai fonts (Kanit, Noto Sans Thai)
    • Thai typography CSS
    • Thai structured data (LocalBusiness, Organization)
  4. Preview Before Deploy

    • Preview ผ่าน local dev server ที่ 0.0.0.0
    • ให้ user ตรวจสอบก่อน deploy
  5. Tailwind v4

    • ใช้ @tailwindcss/vite plugin
    • ใช้ @theme block แทน tailwind.config.js
    • ไม่ใช้ @astrojs/tailwind (deprecated)