☰ 분류

Astro v6 아키텍처 프롬프트

Astro 프로젝트 질문이나 코드를 넣으면 HTML 우선, Islands Architecture, 명시적 hydration, 서버 우선 로직을 기준으로 답하게 합니다.

분류개발 › 코딩
태그초안작성검토개발자코드
프롬프트 (영어 본문 · 답은 한국어로 옵니다)
# Astro v6 Architecture Rules (Strict Mode)

## 1. Core Philosophy

- Follow Astro’s “HTML-first / zero JavaScript by default” principle:
  - Everything is static HTML unless interactivity is explicitly required.
  - JavaScript is a cost → only add when it creates real user value.

- Always think in “Islands Architecture”:
  - The page is static HTML
  - Interactive parts are isolated islands
  - Never treat the whole page as an app

- Before writing any JavaScript, always ask:
  "Can this be solved with HTML + CSS or server-side logic?"

---

## 2. Component Model

- Use `.astro` components for:
  - Layout
  - Composition
  - Static UI
  - Data fetching
  - Server-side logic (frontmatter)

- `.astro` components:
  - Run at build-time or server-side
  - Do NOT ship JavaScript by default
  - Must remain framework-agnostic

- NEVER use React/Vue/Svelte hooks inside `.astro`

---

## 3. Islands (Interactive Components)

- Only use framework components (React, Vue, Svelte, etc.) for interactivity.

- Treat every interactive component as an isolated island:
  - Independent
  - Self-contained
  - Minimal scope

- NEVER:
  - Hydrate entire pages or layouts
  - Wrap large trees in a single island
  - Create many small islands in loops unnecessarily

- Prefer:
  - Static list rendering
  - Hydrate only the minimal interactive unit

---

## 4. Hydration Strategy (Critical)

- Always explicitly define hydration using `client:*` directives.

- Choose the LOWEST possible priority:

  - `client:load`
    → Only for critical, above-the-fold interactivity

  - `client:idle`
    → For secondary UI after page load

  - `client:visible`
    → For below-the-fold or heavy components

  - `client:media`
    → For responsive / conditional UI

  - `client:only`
    → ONLY when SSR breaks (window, localStorage, etc.)

- Default rule:
  ❌ Never default to `client:load`
  ✅ Prefer `client:visible` or `client:idle`

- Hydration is a performance budget:
  - Every island adds JS
  - Keep total JS minimal

📌 Astro does NOT hydrate components unless explicitly told via `client:*` :contentReference[oaicite:0]{index=0}  

---

## 5. Server vs Client Logic

- Prefer server-side logic (inside `.astro` frontmatter) for:
  - Data fetching
  - Transformations
  - Filtering / sorting
  - Derived values

- Only use client-side state when:
  - User interaction requires it
  - Real-time updates are needed

- Avoid:
  - Duplicating logic on client
  - Moving server logic into islands

---

## 6. State Management

- Avoid client state unless strictly necessary.

- If needed:
  - Scope state inside the island only
  - Do NOT create global app state unless required

- For cross-island state:
  - Use lightweight shared stores (e.g., nano stores)
  - Avoid heavy global state systems by default

---

## 7. Performance Constraints (Hard Rules)

- Minimize JavaScript shipped to client:
  - Astro only loads JS for hydrated components :contentReference[oaicite:1]{index=1}  

- Prefer:
  - Static rendering
  - Partial hydration
  - Lazy hydration

- Avoid:
  - Hydrating large lists
  - Repeated islands in loops
  - Overusing `client:load`

- Each island:
  - Has its own bundle
  - Loads independently
  - Should remain small and focused :contentReference[oaicite:2]{index=2}  

---

## 8. File & Project Structure

- `/pages`
  - Entry points (SSG/SSR)
  - No client logic

- `/components`
  - Shared UI
  - Islands live here

- `/layouts`
  - Static wrappers only

- `/content`
  - Markdown / CMS data

- Keep `.astro` files focused on composition, not behavior

---

## 9. Anti-Patterns (Strictly Forbidden)

- ❌ Using hooks in `.astro`
- ❌ Turning Astro into SPA architecture
- ❌ Hydrating entire layout/page
- ❌ Using `client:load` everywhere
- ❌ Mapping lists into hydrated components
- ❌ Using client JS for static problems
- ❌ Replacing server logic with client logic

---

## 10. Preferred Patterns

- ✅ Static-first rendering
- ✅ Minimal, isolated islands
- ✅ Lazy hydration (`visible`, `idle`)
- ✅ Server-side computation
- ✅ HTML + CSS before JS
- ✅ Progressive enhancement

---

## 11. Decision Framework (VERY IMPORTANT)

For every feature:

1. Can this be static HTML?
   → YES → Use `.astro`

2. Does it require interaction?
   → NO → Stay static

3. Does it require JS?
   → YES → Create an island

4. When should it load?
   → Choose LOWEST priority `client:*`

---

## 12. Mental Model (Non-Negotiable)

- Astro is NOT:
  - Next.js
  - SPA framework
  - React-first system

- Astro IS:
  - Static-first renderer
  - Partial hydration system
  - Performance-first architecture

- Think:
  ❌ “Build an app”
  ✅ “Ship HTML + sprinkle JS”

어떤 프롬프트인가

Astro v6 개발에서 정적 HTML과 최소 JavaScript 원칙을 강제하는 아키텍처 규칙이다. client:* 지시문 선택과 섬 구조를 중시하며, 잘린 본문 기준으로는 초반 규칙만 확인된다.

모델 비교

ChatGPT가 가장 정확하고 목적에 맞게 간결하다. Claude는 구체적이나 과도하며, Gemini는 반복 아일랜드를 일부 남긴다.

ChatGPT종합 1위
46/ 50

+ 핵심 판단과 수정안을 간결하고 정확히 제시했다.

- 상품 수만큼 별도 번들이 생긴다는 표현은 부정확하다.

Claude
40/ 50

+ 정적 카드와 최소 아일랜드 구조를 구체화했다.

- 가정한 장바구니 구현이 과하고 예시도 미완성이다.

Gemini
40/ 50

+ 각 요소의 문제와 대안을 체계적으로 비교했다.

- 버튼별 아일랜드로 반복 비용을 충분히 줄이지 못했다.

기준ChatGPTClaudeGemini앞선 모델
지시 준수1098ChatGPT +11%
정확성977ChatGPT +29%
구체성899동점
구성·가독성999동점
분량 적정성1067ChatGPT +43%

gpt-5.6-sol가 모델 이름을 가린 채 1~10점으로 채점했습니다 (2026-09-24). 측정값이 아니라 AI 심사 결과입니다.

답 전문 보기

같은 입력을 세 모델에 넣어 받은 답을 그대로 옮겼습니다. 각 CLI(에이전트 하네스)에서 실행했습니다. ChatGPT·Claude 앱이나 웹에서는 답이 다를 수 있습니다.

넣은 입력
[붙여 넣은 자료]
이 규칙에 맞춰서 아래 상품 목록 페이지 컴포넌트를 리뷰하고 고쳐줘. 전부 client:load를 걸어놔서 그런지 초기 로딩이 느리다는 피드백을 받았어.

```astro
---
import ProductCard from '../components/ProductCard.jsx';
import Header from '../components/Header.jsx';
import Footer from '../components/Footer.jsx';
import { getProducts } from '../lib/api';

const products = await getProducts();
---
<html>
  <body>
    <Header client:load />
    <main>
      {products.map((p) => (
        <ProductCard client:load product={p} />
      ))}
    </main>
    <Footer client:load />
  </body>
</html>
```

상품 카드처럼 반복되는 걸 이렇게 하이드레이트해도 되는지, Header/Footer는 굳이 client:load가 필요한지 판단해서 고쳐줘.
gpt-5.6-luna (codex CLI · 에이전트 하네스) · 실행일 2026-09-24

반복되는 ProductCard마다 client:load를 붙이는 것은 피해야 합니다. 상품 수만큼 JS 번들과 하이드레이션 작업이 발생해 초기 로딩이 느려집니다.

Header와 Footer도 정적 UI라면 client:load가 필요 없습니다. .astro 컴포넌트로 변경하고, 상호작용이 필요한 부분만 별도 island로 분리하는 것이 좋습니다.

---
import ProductCard from '../components/ProductCard.astro';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
import { getProducts } from '../lib/api';

const products = await getProducts();
---

<html lang="ko">
  <body>
    <Header />

    <main>
      {products.map((product) => (
        <ProductCard product={product} />
      ))}
    </main>

    <Footer />
  </body>
</html>

판단은 다음과 같습니다.

  • ProductCard: 상품명, 이미지, 가격, 링크처럼 정적인 내용이면 .astro로 작성하고 하이드레이트하지 않습니다.
  • Header: 로고와 내비게이션만 있으면 .astro로 작성합니다. 모바일 메뉴가 필요하다면 Header 전체가 아니라 메뉴 토글만 별도 컴포넌트로 분리합니다.
<!-- Header.astro -->
---
import MobileMenuButton from './MobileMenuButton.jsx';
---

<header>
  <a href="/">브랜드</a>
  <nav>...</nav>

  <MobileMenuButton client:idle />
</header>
  • Footer: 정적 링크와 정보만 있으면 하이드레이션하지 않습니다.
  • 상품 카드의 장바구니 버튼처럼 상호작용이 필요해도 카드 전체를 island로 만들지 말고, 버튼만 분리합니다. 다만 카드마다 island를 반복하면 비용이 커질 수 있으므로 가능하면 HTML <form>과 서버 처리 또는 링크 기반으로 구현하는 편이 좋습니다.

client:visible로 바꾸는 것만으로는 반복 island 문제가 해결되지 않습니다. 각 카드가 정말 클라이언트 상태를 필요로 할 때만 제한적으로 사용하세요.

같은 분류의 프롬프트

방산 CV 12개월 로드맵 프롬프트
2046 퍼즐 게임 제작 프롬프트
React 컴포넌트 통합 프롬프트
3D 아바타 팩토리 요구 프롬프트
3D FPS 게임 개발 프롬프트