Astro 완벽 가이드 | 정적 사이트·컴포넌트 아일랜드·콘텐츠 컬렉션·성능·SEO

Astro 완벽 가이드 | 정적 사이트·컴포넌트 아일랜드·콘텐츠 컬렉션·성능·SEO

이 글의 핵심

Astro로 초고속 정적 사이트를 구축하는 완벽 가이드입니다. 컴포넌트 아일랜드, 콘텐츠 컬렉션, 다중 프레임워크 통합까지 실전 예제로 정리했습니다.

실무 경험 공유: Next.js에서 Astro로 블로그를 전환하면서, Lighthouse 점수가 95에서 100으로 향상되고 빌드 시간이 70% 단축된 경험을 공유합니다.

들어가며: “사이트가 느려요”

실무 문제 시나리오

시나리오 1: JavaScript 번들이 너무 커요
SPA는 무겁습니다. Astro는 기본적으로 JS를 제거합니다.

시나리오 2: SEO가 중요해요
CSR은 SEO가 약합니다. Astro는 완벽한 SSG를 제공합니다.

시나리오 3: 빌드가 느려요
복잡한 프레임워크는 느립니다. Astro는 초고속 빌드를 제공합니다.


1. Astro란?

핵심 특징

Astro는 콘텐츠 중심 웹사이트를 위한 프레임워크입니다.

주요 장점:

  • Zero JS: 기본적으로 JS 없음
  • 컴포넌트 아일랜드: 필요한 곳만 hydration
  • 다중 프레임워크: React, Vue, Svelte 동시 사용
  • 콘텐츠 컬렉션: Markdown/MDX 관리
  • 빠른 빌드: Vite 기반

2. 프로젝트 설정

설치

npm create astro@latest

프로젝트 구조

my-astro-site/
├── src/
│   ├── components/
│   │   └── Header.astro
│   ├── layouts/
│   │   └── Layout.astro
│   ├── pages/
│   │   ├── index.astro
│   │   └── blog/
│   │       └── [slug].astro
│   └── content/
│       └── blog/
│           └── post-1.md
├── public/
└── astro.config.mjs

3. 컴포넌트

Astro 컴포넌트

---
// src/components/Card.astro
interface Props {
  title: string;
  description: string;
}

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

<div class="card">
  <h2>{title}</h2>
  <p>{description}</p>
</div>

<style>
  .card {
    padding: 1rem;
    border: 1px solid #ccc;
    border-radius: 8px;
  }
</style>

레이아웃

---
// src/layouts/Layout.astro
interface Props {
  title: string;
}

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

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>{title}</title>
  </head>
  <body>
    <header>
      <nav>
        <a href="/">Home</a>
        <a href="/blog">Blog</a>
      </nav>
    </header>
    <main>
      <slot />
    </main>
  </body>
</html>

4. 컴포넌트 아일랜드

client:load

---
import Counter from './Counter.jsx';
---

<!-- 페이지 로드 시 즉시 hydrate -->
<Counter client:load />

client:visible

<!-- 뷰포트에 보일 때 hydrate -->
<HeavyComponent client:visible />

client:idle

<!-- 브라우저가 idle일 때 hydrate -->
<Chat client:idle />

client:only

<!-- SSR 없이 클라이언트에서만 렌더링 -->
<ClientOnlyWidget client:only="react" />

5. 콘텐츠 컬렉션

설정

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

const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.date(),
    tags: z.array(z.string()),
    author: z.string(),
  }),
});

export const collections = { blog };

마크다운 작성

---
title: 'My First Post'
description: 'This is my first post'
pubDate: 2026-06-03
tags: ['astro', 'blog']
author: 'JB'
---

# Hello World

This is my first post!

페이지에서 사용

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

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

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

<Layout title={post.data.title}>
  <article>
    <h1>{post.data.title}</h1>
    <p>{post.data.description}</p>
    <Content />
  </article>
</Layout>

6. 다중 프레임워크

React 통합

npx astro add react
---
import ReactCounter from './ReactCounter.jsx';
---

<ReactCounter client:load />

Vue 통합

npx astro add vue
---
import VueComponent from './VueComponent.vue';
---

<VueComponent client:visible />

7. API Routes

// src/pages/api/posts.json.ts
import type { APIRoute } from 'astro';
import { getCollection } from 'astro:content';

export const GET: APIRoute = async () => {
  const posts = await getCollection('blog');

  return new Response(JSON.stringify(posts), {
    status: 200,
    headers: {
      'Content-Type': 'application/json',
    },
  });
};

export const POST: APIRoute = async ({ request }) => {
  const data = await request.json();

  // 처리 로직

  return new Response(JSON.stringify({ success: true }), {
    status: 201,
    headers: {
      'Content-Type': 'application/json',
    },
  });
};

8. 배포

Cloudflare Pages

npm run build
// package.json
{
  "scripts": {
    "build": "astro build",
    "preview": "astro preview"
  }
}

정리 및 체크리스트

핵심 요약

  • Astro: 콘텐츠 중심 프레임워크
  • Zero JS: 기본적으로 JS 없음
  • 컴포넌트 아일랜드: 선택적 hydration
  • 콘텐츠 컬렉션: Markdown 관리
  • 다중 프레임워크: React, Vue, Svelte
  • 빠른 빌드: Vite 기반

구현 체크리스트

  • Astro 설치
  • 레이아웃 작성
  • 컴포넌트 작성
  • 콘텐츠 컬렉션 설정
  • 컴포넌트 아일랜드 구현
  • API Routes 구현
  • 배포

같이 보면 좋은 글

  • Next.js App Router 가이드
  • SvelteKit 완벽 가이드
  • Vite 5 완벽 가이드

이 글에서 다루는 키워드

Astro, Static Site, SSG, Performance, SEO, Content, Frontend

자주 묻는 질문 (FAQ)

Q. Next.js와 비교하면 어떤가요?

A. Astro가 정적 사이트에 특화돼 더 빠릅니다. Next.js는 동적 기능이 더 강력합니다.

Q. 블로그에 적합한가요?

A. 네, 완벽합니다. 콘텐츠 컬렉션과 Markdown 지원이 탁월합니다.

Q. React 컴포넌트를 사용할 수 있나요?

A. 네, React, Vue, Svelte 등 다양한 프레임워크를 동시에 사용할 수 있습니다.

Q. SEO가 좋은가요?

A. 네, 완벽한 SSG로 SEO가 매우 좋습니다.

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3