테마 전환

Astro 블로그 처음부터 만들기: 1시간 만에 홈페이지부터 배포까지 완성하는 가이드

Easton editorial illustration: deployment dock

기술 블로그가 0.8초 만에 완전히 로드되고 페이지 전환도 매끄러웠습니다. 제 WordPress 블로그를 다시 보니 3초 동안 빈 화면이 이어져 그냥 닫고 싶을 정도였습니다. 이전에는 Hexo와 Hugo를 만져 봤고 Gatsby까지 시도했지만, 매번 어느 지점에서 막혔습니다. 공식 문서는 이해하기 어렵고 튜토리얼은 지나치게 단편적이라 설치부터 배포까지 늘 무언가 빠진 느낌이었습니다. Astro는 성능이 뛰어나고 개발 경험도 좋았으며, 전체 과정이 생각보다 훨씬 간단했습니다.

이 글에서는 처음 시작해 배포하기까지의 전 과정을 안내합니다. 1시간 안에 홈페이지, 글 목록, 태그 분류, RSS 구독을 갖춘 완전한 블로그를 공개할 수 있습니다. 실제로 따라 할 수 있는 구체적인 단계만 담았습니다.

1장: 왜 Astro를 선택해야 할까요? (광고가 아니라 정말 편리합니다)

성능 차이가 정말 그렇게 클까요?

솔직히 저도 처음에는 반신반의했습니다. 공식 사이트에서 말하는 ‘기존 React 프레임워크보다 40% 빠름’, ‘기본 JavaScript 출력 0’ 같은 표현은 마케팅 문구처럼 들리지 않나요? 하지만 WordPress 블로그를 실제로 Astro로 옮겨 보니 수치가 결과를 분명히 보여 줬습니다.

  • 첫 화면 로딩 시간: 3.2초에서 0.8초로 감소
  • Lighthouse 점수: 100점 달성(기존 WordPress는 65점)
  • JavaScript 용량: 280KB에서 20KB 미만으로 감소
0.8초
첫 화면 로딩 시간
3.2초에서 0.8초로 감소
100점
Lighthouse 점수
기존 WordPress는 65점
93%
JS 용량 감소
280KB에서 20KB 미만으로 감소

이렇게 큰 성능 향상이 어떻게 가능한지 궁금할 수 있습니다. 비밀은 Astro의 핵심 철학인 콘텐츠 우선, JavaScript는 필요할 때만 로드에 있습니다. Astro는 기본적으로 순수 HTML+CSS를 출력하고, 명시적으로 상호작용이 필요한 곳에만 JavaScript를 로드합니다. 이는 모든 요소를 한꺼번에 포함하는 React식 접근과 정반대입니다.

흥미로운 비교도 해 봤습니다. 같은 글을 Next.js와 Astro에서 각각 테스트했더니 Next.js는 첫 화면에서 약 100KB의 프레임워크 런타임을 로드했지만 Astro는 깔끔한 HTML 파일 하나뿐이었습니다. 읽기가 중심인 블로그에서는 이 차이가 특히 크게 느껴집니다.

개발 경험은 어떤가요?

성능에 이어 개발 경험을 살펴보겠습니다. 제가 Astro에서 가장 좋아하는 부분은 Islands 아키텍처입니다. 거창하게 들리지만 실제 뜻은 ‘상호작용이 필요한 곳에서만 JavaScript를 쓴다’는 것입니다.

예를 들어 글 상세 페이지가 있다면 다음처럼 구성할 수 있습니다.

  • 글 본문 → 정적 HTML(빠름)
  • 댓글 영역 → React 컴포넌트 사용(상호작용 가능)
  • 내비게이션 바 → Vue 컴포넌트 사용(네, 함께 쓸 수 있습니다!)

이런 유연성 덕분에 작은 기능 하나를 위해 사이트 전체를 SPA로 만들 필요가 없습니다. Astro가 초보자에게 특히 친절한 또 다른 이유는 Markdown으로 바로 글을 쓸 수 있다는 점입니다. 데이터베이스나 백오피스 관리 시스템을 구성할 필요가 없습니다. 저는 이제 VSCode에서 Markdown으로 글을 쓰고 GitHub에 푸시하면 자동으로 배포되도록 사용합니다. 아주 편합니다.

다른 프레임워크와 비교하면 어떤가요?

저도 오랫동안 고민했던 부분이라 궁금할 것이라 생각합니다. 현실적인 표로 비교해 보겠습니다.

프레임워크적합한 용도학습 곡선성능유지보수 비용
Astro블로그/문서 사이트낮음(HTML만 알면 됨)⭐⭐⭐⭐⭐낮음(유지보수가 거의 필요 없음)
Next.js복잡한 애플리케이션중간(React 이해 필요)⭐⭐⭐⭐중간(API 유지보수 필요)
Hexo순수 정적 블로그낮음(확장성은 부족)⭐⭐⭐낮음
WordPressCMS가 필요한 경우중간(플러그인 생태계가 좋음)⭐⭐높음(보안과 업데이트가 번거로움)

제 의견은 다음과 같습니다.

  • 블로그나 기술 문서 사이트를 만든다면 성능과 개발 경험이 모두 좋은 Astro를 우선 추천합니다.
  • 전자상거래나 상호작용이 복잡한 애플리케이션이라면 Next.js가 더 적합합니다.
  • 사용자 지정 기능이 필요 없는 가장 단순한 정적 블로그를 원한다면 Hexo로도 충분합니다.
  • 비기술 팀도 글을 발행할 수 있는 관리 화면이 필요하다면 WordPress가 맞습니다.

참고로 2025년 자료에 따르면 Astro의 npm 다운로드 수는 300만 회를 넘어섰고 시장 점유율은 18%까지 성장했습니다. 점점 더 많은 개발자가 실제 선택으로 지지하고 있으므로 더 이상 틈새 프레임워크가 아닙니다.

2장: 환경 준비(5분이면 완료)

Node.js 설치(아직 설치하지 않았다면)

Astro에는 Node.js v18 이상이 필요합니다. 먼저 버전을 확인합니다.

node -v
npm -v

버전 번호가 표시된다면 이 단계는 건너뛰면 됩니다. 설치되어 있지 않다면 Node.js 공식 사이트에서 LTS 버전을 다운로드하세요.

Windows 사용자가 주의할 점: 설치할 때 ‘Add to PATH’를 반드시 선택해야 이후 명령을 찾을 수 있습니다. 일부 백신 프로그램이 npm 설치를 차단하기도 하므로 설치 후 명령줄을 한 번 다시 시작하는 것이 좋습니다.

Astro 프로젝트 생성

생각보다 간단합니다. 명령줄을 열고 다음을 입력합니다.

npm create astro@latest

여러 선택지가 나타나도 당황하지 마세요. 다음처럼 고르면 됩니다.

  1. 프로젝트 이름: 자유롭게 지정합니다. 예: my-blog
  2. 템플릿 선택: Blog 템플릿을 선택합니다(방향키+Enter).
  3. 의존성 설치: Yes를 선택합니다.
  4. TypeScript 설정: Strict 또는 Strictest를 선택합니다. 타입 검사는 많은 버그를 미리 막아 줍니다.
  5. Git 저장소 초기화: Yes를 선택합니다.

전체 과정은 약 1~2분이며 템플릿과 의존성 패키지가 자동으로 다운로드됩니다.

Blog 템플릿을 추천하는 이유는 무엇일까요? 글 목록, 태그 분류, RSS 구독의 기본 코드가 이미 포함되어 있어 빈 템플릿에서 시작하는 것보다 훨씬 빠릅니다. 저는 처음 빈 템플릿을 썼을 때 페이지네이션 하나에만 두 시간을 썼습니다.

개발 서버 시작

프로젝트 디렉터리로 이동해 서버를 시작합니다.

cd my-blog
npm run dev

Local: http://localhost:4321이 보이면 성공입니다. 브라우저에서 이 주소를 열면 이미 만들어진 블로그 뼈대를 확인할 수 있습니다.

초보자가 주의할 점:

  • 4321 포트를 다른 프로그램이 사용 중이라면 astro.config.mjs 파일의 server.port를 변경할 수 있습니다.
  • 시작할 때 EACCES 오류가 발생하면 권한 문제일 수 있습니다. Mac/Linux에서는 sudo npm run dev를 시도해 보세요.
  • 글자가 깨진다면 명령줄 인코딩이 UTF-8인지 확인하세요.

여기까지 하면 환경 준비가 끝났습니다. 이제 실행 가능한 Astro 블로그가 생겼으니 다음으로 각 파일의 역할을 살펴보겠습니다.

3장: 프로젝트 구조 자세히 알아보기(각 폴더의 역할)

프로젝트 디렉터리는 어떻게 생겼나요?

VSCode나 다른 편집기로 my-blog 폴더를 열면 다음과 같은 구조가 보입니다.

my-blog/
├── src/
│   ├── pages/           # 라우트 페이지, 파일 이름이 곧 URL
│   ├── layouts/         # 레이아웃 템플릿(헤더, 푸터 등)
│   ├── components/      # 재사용 컴포넌트(버튼, 카드 등)
│   └── content/         # Markdown 글 저장 위치
├── public/              # 정적 리소스(이미지, 글꼴, favicon)
├── astro.config.mjs     # Astro 설정 파일
└── package.json         # 프로젝트 의존성

일반적인 프론트엔드 프로젝트와 비슷해 보입니다. 하지만 Astro에는 몇 가지 특별한 점이 있고, 이를 이해하면 왜 사용하기 편리한지 알 수 있습니다.

pages/ 디렉터리: 파일이 곧 라우트

제가 Astro에서 가장 좋아하는 부분입니다. 라우트를 별도로 설정할 필요 없이 파일 이름이 자동으로 URL에 대응합니다.

  • pages/index.astro → 사이트 홈페이지 /
  • pages/about.astro → 소개 페이지 /about
  • pages/blog/index.astro → 블로그 목록 /blog
  • pages/blog/[...slug].astro → 글 상세 페이지 /blog/xxx

마지막 [...slug].astro는 동적 라우트입니다. 대괄호로 감싼 부분이 변수가 되며, 이 파일이 /blog/ 아래의 모든 글 링크를 처리합니다.

Next.js의 라우팅 시스템보다 훨씬 단순합니다. Next에서 이전해 왔을 때 이 설계가 바로 마음에 들었습니다.

content/ 디렉터리: 글 저장 위치

src/content/blog/ 폴더를 열면 예시 글이 몇 개 들어 있습니다. 각 글은 .md 또는 .mdx 파일이며, 맨 앞에는 Frontmatter(세 개의 하이픈으로 감싼 부분)가 있습니다.


---

title: '我的第一篇文章'
description: '这是一篇测试文章'
pubDate: 'Dec 02 2025'
heroImage: '/blog-placeholder.jpg'
tags: ['Astro', '教程']

---

这里开始写正文...

Astro는 이 정보를 자동으로 인식하며 페이지에서 post.data.title처럼 호출할 수 있습니다. 타입 검사도 지원하므로 필드 이름을 잘못 쓰면 빌드할 때 오류가 납니다. 꼼꼼하게 관리하기에 좋습니다.

layouts/components/: 코드 재사용

layouts/에는 모든 글에서 공통으로 사용하는 헤더, 푸터, 사이드바 등의 페이지 레이아웃을 둡니다. Blog 템플릿에는 BaseLayout.astroBlogPost.astro 두 레이아웃이 기본으로 포함되어 있습니다.

components/에는 버튼, 카드, 태그 클라우드처럼 재사용하는 작은 컴포넌트를 둡니다. Astro 문법으로 작성할 수도 있고 React/Vue를 바로 사용할 수도 있어 매우 유연합니다.

public/ 디렉터리: 출력 폴더로 그대로 복사

이곳의 파일은 최종 사이트의 루트 디렉터리에 원본 그대로 복사됩니다. 예를 들어 public/favicon.ico는 배포 후 https://你的域名/favicon.ico가 됩니다.

저는 일반적으로 블로그 이미지, 글꼴 파일, robots.txt 등을 이곳에 둡니다.

astro.config.mjs: 핵심 설정 파일

이 파일은 Astro의 동작을 제어합니다. 자주 사용하는 설정은 다음과 같습니다.

export default defineConfig({
  site: 'https://你的域名.com',  // 배포할 도메인
  integrations: [mdx()],            // 플러그인(Markdown 확장, RSS 등)
  server: {
    port: 4321                       // 개발 서버 포트
  }
})

지금은 많이 변경할 필요가 없습니다. 뒤에서 기능을 추가할 때 다시 조정하면 됩니다.

이 디렉터리 구조를 이해하는 것은 정말 중요합니다. 바로 코딩을 시작했다가 파일을 어디에 둘지 몰라 프로젝트 구조가 뒤죽박죽된 사례를 많이 봤습니다. 5분만 투자해 구조를 파악하면 이후 한 시간을 아낄 수 있습니다.

4장: 핵심 기능 구현(이제부터가 중요합니다)

4.1 홈페이지 레이아웃: 최신 글 표시

Blog 템플릿이 홈페이지 뼈대를 이미 만들어 주지만, 조금 더 실용적으로 다듬어 보겠습니다. src/pages/index.astro를 열면 다음과 비슷한 코드가 보입니다.


---

import { getCollection } from 'astro:content';
import BaseLayout from '../layouts/BaseLayout.astro';

// 모든 블로그 글을 가져와 날짜순으로 정렬한 뒤 최신 5개 선택
const allPosts = (await getCollection('blog'))
  .sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf())
  .slice(0, 5);

---

<BaseLayout>
  <h1>欢迎来到我的博客</h1>
  <ul>
    {allPosts.map((post) => (
      <li>
        <a href={`/blog/${post.slug}/`}>{post.data.title}</a>
        <time>{post.data.pubDate.toDateString()}</time>
      </li>
    ))}
  </ul>
</BaseLayout>

이 코드는 무엇을 하나요?

  1. getCollection('blog')로 모든 글을 가져옵니다.
  2. 발행일의 역순으로 정렬합니다(최신 글이 앞에 옵니다).
  3. slice(0, 5)로 앞의 글 5개만 선택합니다.
  4. 반복 렌더링해 목록을 만듭니다.

초보자가 주의할 점: 날짜를 정렬할 때는 .valueOf()를 사용해야 합니다. 그렇지 않으면 문자열순으로 정렬되어 결과가 뒤섞입니다.

4.2 글 목록 페이지: 페이지네이션 포함

src/pages/blog/index.astro를 생성하고(템플릿에 없다면) 완전한 글 목록을 구현합니다.


---

import { getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';

const allPosts = (await getCollection('blog'))
  .sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());

const pageSize = 10;
const currentPage = 1;
const totalPages = Math.ceil(allPosts.length / pageSize);
const posts = allPosts.slice(0, pageSize);

---

<BaseLayout title="文章列表">
  <h1>所有文章</h1>

  <div class="post-list">
    {posts.map((post) => (
      <article>
        <h2><a href={`/blog/${post.slug}/`}>{post.data.title}</a></h2>
        <p>{post.data.description}</p>
        <time>{post.data.pubDate.toLocaleDateString('zh-CN')}</time>
        <div class="tags">
          {post.data.tags?.map(tag => <span>#{tag}</span>)}
        </div>
      </article>
    ))}
  </div>

  {totalPages > 1 && (
    <div class="pagination">
      <span>第 {currentPage} / {totalPages} 页</span>
    </div>
  )}
</BaseLayout>

여기서는 페이지네이션 로직을 단순화했습니다. 실제 프로젝트에서는 Astro의 paginate() 함수로 페이지를 자동 생성할 수 있습니다. 하지만 글이 많지 않은 블로그(100개 미만)라면 한 페이지에 모두 보여 줘도 충분합니다.

사용자 경험 개선 제안:

  • 예상 읽기 시간 추가(글자 수÷분당 400자 기준)
  • 글 요약을 150자에서 자르고 말줄임표 추가
  • 썸네일 추가(heroImage 필드 사용)

4.3 글 상세 페이지: 가장 핵심적인 페이지

가장 중요한 부분으로 동적 라우트를 사용합니다. Blog 템플릿에 src/pages/blog/[...slug].astro가 있다면 바로 편집하고, 없다면 새로 만듭니다.


---

import { getCollection } from 'astro:content';
import BlogPost from '../../layouts/BlogPost.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();

---

<BlogPost {...post.data}>
  <Content />
</BlogPost>

이 코드가 동작하는 방식:

  • getStaticPaths()는 빌드할 때 실행되어 글마다 정적 HTML을 생성합니다.
  • post.render()는 Markdown을 HTML 컴포넌트로 변환합니다.
  • <Content />가 글의 본문입니다.

초보자가 자주 막히는 부분:

  1. 코드 강조가 적용되지 않음: Shiki 플러그인을 설치해야 합니다(Blog 템플릿에는 기본 포함).
  2. Markdown 스타일이 보기 좋지 않음: @tailwindcss/typography 플러그인을 권장합니다.
  3. 이미지 경로 오류: 이미지를 public/ 폴더에 두고 /images/xxx.jpg처럼 참조합니다.

목차(TOC)를 추가하려면 커뮤니티 플러그인 remark-toc를 사용해 astro.config.mjs에 설정할 수 있습니다.

import { defineConfig } from 'astro/config';
import remarkToc from 'remark-toc';

export default defineConfig({
  markdown: {
    remarkPlugins: [remarkToc],
  },
});

4.4 태그 분류 시스템: 콘텐츠를 더 체계적으로 관리

src/pages/tags/[tag].astro를 만들고 태그 필터링 기능을 구현합니다.


---

import { getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';

export async function getStaticPaths() {
  const allPosts = await getCollection('blog');

  // 고유한 태그 모두 수집
  const allTags = [...new Set(allPosts.flatMap(post => post.data.tags || []))];

  // 태그마다 페이지 생성
  return allTags.map(tag => ({
    params: { tag },
    props: {
      posts: allPosts.filter(post =>
        post.data.tags?.includes(tag)
      ).sort((a, b) =>
        b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
      ),
    },
  }));
}

const { tag } = Astro.params;
const { posts } = Astro.props;

---

<BaseLayout title={`标签: ${tag}`}>
  <h1>#{tag} 相关文章 ({posts.length})</h1>

  <ul>
    {posts.map((post) => (
      <li>
        <a href={`/blog/${post.slug}/`}>{post.data.title}</a>
      </li>
    ))}
  </ul>
</BaseLayout>

이제 태그마다 /tags/astro, /tags/教程 같은 독립 페이지가 생성됩니다.

고급 활용법: 태그 클라우드 페이지(src/pages/tags/index.astro)를 만들어 모든 태그와 글 수를 표시하고, 글 수에 따라 글꼴 크기를 동적으로 바꾸면 멋진 효과를 낼 수 있습니다.

4.5 RSS 구독: 독자가 새 글을 바로 받도록 설정

RSS 플러그인을 설치합니다.

npx astro add rss

src/pages/rss.xml.js를 생성합니다.

import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';

export async function GET(context) {
  const posts = await getCollection('blog');

  return rss({
    title: '我的技术博客',
    description: '分享前端开发经验和学习心得',
    site: context.site,
    items: posts.map((post) => ({
      title: post.data.title,
      pubDate: post.data.pubDate,
      description: post.data.description,
      link: `/blog/${post.slug}/`,
    })),
  });
}

배포 후 RSS 구독 주소는 https://你的域名.com/rss.xml이 됩니다. 요즘 RSS 사용자가 많지는 않지만 기술 블로그에 추가하면 전문적인 인상을 줍니다.

여기까지 핵심 기능을 모두 만들었습니다. 이제 홈페이지, 글 목록, 상세 페이지, 태그 분류, RSS 구독을 갖춘 완전한 블로그 시스템이 생겼습니다. 다음으로 검색 엔진에 더 친화적으로 만들어 보겠습니다.

5장: SEO 최적화(다른 사람이 블로그를 찾게 만들기)

블로그를 만든 것으로 끝이 아닙니다. 다른 사람이 찾을 수 있어야 합니다. 이것이 SEO(검색 엔진 최적화)의 의미입니다. 다행히 Astro는 정적 HTML, 빠른 로딩, 시맨틱 태그 등 검색 엔진이 선호하는 요소를 기본적으로 갖추고 있습니다.

Meta 태그 설정: 페이지 내용을 검색 엔진에 알리기

src/layouts/BaseLayout.astro 또는 기본 레이아웃 파일을 열고 <head> 태그 안에 다음 내용을 추가합니다.


---

interface Props {
  title: string;
  description?: string;
  image?: string;
}

const { title, description = '我的技术博客', image = '/og-image.jpg' } = Astro.props;
const canonicalURL = new URL(Astro.url.pathname, Astro.site);

---

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width" />
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />

  <title>{title} | 我的博客</title>
  <meta name="description" content={description} />
  <link rel="canonical" href={canonicalURL} />

  <!-- Open Graph (소셜 미디어 공유) -->
  <meta property="og:title" content={title} />
  <meta property="og:description" content={description} />
  <meta property="og:image" content={new URL(image, Astro.site)} />
  <meta property="og:url" content={canonicalURL} />

  <!-- Twitter Card -->
  <meta name="twitter:card" content="summary_large_image" />
  <meta name="twitter:title" content={title} />
  <meta name="twitter:description" content={description} />
  <meta name="twitter:image" content={new URL(image, Astro.site)} />
</head>

이제 모든 페이지에 완전한 Meta 정보가 포함되며, 메시지 앱이나 Twitter에 공유할 때도 보기 좋은 카드가 표시됩니다.

Sitemap 생성: 검색 엔진에 페이지 목록 알리기

명령 한 줄이면 됩니다.

npx astro add sitemap

그런 다음 astro.config.mjs에 도메인을 설정합니다.

export default defineConfig({
  site: 'https://你的域名.com',
  integrations: [sitemap()],
});

배포 후 sitemap은 https://你的域名.com/sitemap-index.xml에 자동 생성됩니다. Google Search Console에 이 주소를 제출하면 며칠 후 글이 검색될 수 있습니다.

성능 최적화: 속도도 SEO의 중요한 요소

Astro는 기본적으로 충분히 빠르지만 몇 가지 팁을 더 적용할 수 있습니다.

1. 이미지 최적화

일반 <img> 태그 대신 Astro의 <Image> 컴포넌트를 사용합니다.


---

import { Image } from 'astro:assets';
import myImage from '../assets/photo.jpg';

---

<Image src={myImage} alt="描述文字" />

이렇게 하면 다음 작업을 자동으로 처리합니다.

  • 최신 형식(WebP/AVIF)으로 변환
  • 여러 크기의 반응형 이미지 생성
  • 지연 로딩

2. CSS/JS 압축

프로덕션 빌드 시 Astro가 자동으로 압축하므로 추가 설정은 필요하지 않습니다. 다만 사용하지 않는 의존성 패키지는 삭제해 용량을 줄이는 것이 좋습니다.

3. 글꼴 최적화

Google Fonts나 사용자 지정 글꼴을 쓴다면 글꼴 로딩이 렌더링을 막지 않도록 font-display: swap을 추가하세요.

@font-face {
  font-family: 'MyFont';
  src: url('/fonts/myfont.woff2') format('woff2');
  font-display: swap;
}

이 최적화를 모두 적용하면 블로그의 Lighthouse 점수는 대체로 95점 이상을 안정적으로 유지할 수 있습니다. 제 블로그도 타사 스크립트 때문에 ‘Best Practices’에서 약간 감점되는 것을 제외하면 다른 항목은 모두 만점입니다.

6장: 배포하기(두 가지 무료 호스팅 플랫폼 중 선택)

코드를 다 작성했다면 이제 가장 설레는 단계입니다. 전 세계 누구나 블로그에 접속할 수 있게 만들어 보겠습니다. 무료이면서 사용하기 좋은 호스팅 플랫폼 두 가지를 소개하니 하나를 선택하면 됩니다.

방법 1: Vercel 배포(초보자에게 권장)

Vercel을 가장 추천합니다. Astro를 기본 지원하므로 별도 설정 없이 실행할 수 있기 때문입니다.

1단계: GitHub에 코드 푸시

아직 저장소를 만들지 않았다면 프로젝트 루트 디렉터리에서 다음을 실행합니다.

git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/你的用户名/my-blog.git
git push -u origin main

2단계: Vercel에서 프로젝트 가져오기

  1. vercel.com에서 가입합니다(GitHub 로그인이 가장 편리합니다).
  2. ‘New Project’를 클릭합니다.
  3. my-blog 저장소를 선택합니다.
  4. Vercel이 Astro 프레임워크를 자동으로 인식하므로 설정을 변경할 필요가 없습니다.
  5. ‘Deploy’를 클릭하고 1~2분 기다립니다.

3단계: 블로그 접속

배포가 끝나면 Vercel이 xxx.vercel.app 도메인을 제공합니다. 바로 접속하면 블로그를 확인할 수 있습니다.

사용자 지정 도메인 연결(선택 사항)

자체 도메인이 있다면 Vercel 프로젝트 설정에 도메인을 추가하고, 도메인 제공 업체에서 Vercel이 안내한 주소를 가리키는 CNAME 레코드를 추가하면 됩니다. Vercel이 구체적인 절차를 안내하므로 매우 간단합니다.

초보자가 주의할 점:

  • astro.config.mjs에 올바른 site 주소를 설정했는지 확인합니다.
  • 환경 변수는 코드에 직접 쓰지 말고 Vercel 관리 화면에서 설정합니다.
  • 첫 배포에는 5분 정도 걸릴 수 있으니 조금 기다리세요.

방법 2: Netlify 배포(대안)

Netlify는 Vercel과 비슷하지만 중국 내 접속 속도가 조금 더 안정적입니다.

1단계: GitHub에 코드 푸시

(Vercel과 마찬가지로 먼저 GitHub에 코드를 푸시합니다.)

2단계: Netlify에서 프로젝트 가져오기

  1. netlify.com에서 가입합니다.
  2. ‘Add new site’ → ‘Import an existing project’를 클릭합니다.
  3. GitHub를 연결하고 저장소를 선택합니다.
  4. 빌드 설정:
    • Build command: npm run build
    • Publish directory: dist
  5. ‘Deploy’를 클릭합니다.

3단계: 블로그 접속

마찬가지로 xxx.netlify.app 도메인이 제공되므로 접속해 테스트합니다.

두 플랫폼 중 무엇을 선택할까요?

플랫폼장점단점적합한 사용자
VercelAstro 자동 인식 및 설정
빠른 엣지 네트워크
좋은 CI/CD 경험
중국 내 접속이 가끔 느림최고의 개발 경험을 원하는 개발자
Netlify중국 내 접속이 안정적
넉넉한 무료 한도
풍부한 플러그인 생태계
설정이 조금 더 복잡함중국어 사용자 대상 블로그

제 의견은 먼저 Vercel을 써 보고 중국 내 접속이 느리면 Netlify로 전환하는 것입니다. 두 플랫폼 모두 자동 배포를 지원하므로 GitHub에 코드를 푸시하면 사이트를 자동으로 빌드하고 업데이트합니다.

자동 배포의 마법

이제 다음 과정만 거치면 됩니다.

  1. 로컬에서 글을 작성합니다(Markdown 파일).
  2. git add .git commit -m "新文章"git push를 실행합니다.
  3. 2분 정도 기다리면 글이 사이트에 자동으로 게시됩니다.

서버에 로그인하거나 수동으로 빌드하고 파일을 업로드할 필요가 없습니다. 이것이 현대적인 배포의 장점이며, 처음 경험했을 때 저도 정말 놀랐습니다.

7장: 자주 묻는 문제와 해결 방법(미리 피해야 할 함정)

이 장은 저와 커뮤니티 구성원이 실제로 겪은 문제를 모았습니다. 미리 알아 두면 많은 시간을 아낄 수 있습니다.

문제 1: Tailwind 스타일이 적용되지 않음

증상: Tailwind 클래스 이름을 작성했지만 페이지에 효과가 나타나지 않습니다.

원인: tailwind.config.mjscontent 경로가 잘못되어 Tailwind가 파일을 스캔하지 못했습니다.

해결 방법:

tailwind.config.mjs를 열고 content 배열에 스캔해야 할 파일이 모두 포함되어 있는지 확인합니다.

export default {
  content: [
    './src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

수정 후 개발 서버를 다시 시작합니다(Ctrl+C로 중지한 뒤 npm run dev 재실행).

문제 2: 빌드 시 ‘Invalid frontmatter’ 오류 발생

증상: 로컬에서는 정상적으로 실행되지만 npm run build에서 오류가 발생합니다.

원인: Markdown 글의 frontmatter 형식이 잘못되었거나 필수 필드가 빠졌습니다.

해결 방법:

src/content/config.ts가 있다면 열어서 어떤 필드가 필수인지 확인합니다. Blog 템플릿은 일반적으로 다음 필드를 요구합니다.


---

title: '文章标题'           # 필수
description: '文章描述'     # 필수
pubDate: 'Dec 02 2025'     # 필수, 날짜 형식 주의
tags: ['标签1', '标签2']   # 선택 사항

---

Content Collections의 장점이 바로 여기에 있습니다. 빌드할 때 유효성을 검사해 운영 환경에서 문제가 생기는 것을 방지합니다.

문제 3: 로컬에서는 정상인데 배포 후 404 발생

증상: 로컬 개발 환경에서는 모두 정상이지만 Vercel/Netlify에 배포한 뒤 글 페이지에 접속하면 404가 표시됩니다.

원인: astro.config.mjsbase 경로가 잘못되었거나 site가 설정되지 않았습니다.

해결 방법:

설정 파일에 다음 내용이 있는지 확인합니다.

export default defineConfig({
  site: 'https://你的域名.com',  // 반드시 설정
  // base: '/blog',  // 하위 디렉터리에 배포할 때만 필요
});

블로그를 하위 디렉터리(예: xxx.com/blog)에 배포하지 않는다면 base를 설정하지 마세요.

문제 4: 이미지 로딩이 매우 느림

증상: 글의 이미지가 느리게 로드되어 사용자 경험이 나빠집니다.

원인: Astro의 Image 컴포넌트로 최적화하지 않았거나 이미지 원본이 너무 큽니다.

해결 방법:

  1. Image 컴포넌트 사용(권장):

---

import { Image } from 'astro:assets';

---

<Image src="/images/photo.jpg" alt="描述" width={800} height={600} />
  1. 이미지 압축: TinyPNG 또는 Squoosh.app으로 압축한 뒤 업로드합니다.

  2. CDN 사용: 이미지를 이미지 호스팅 서비스(Cloudinary, Imgur 등)에 두고 CDN 링크로 참조합니다.

문제 5: 코드 블록에 구문 강조가 표시되지 않음

증상: Markdown 코드 블록이 색상 없이 일반 텍스트로 표시됩니다.

원인: 테마가 설정되지 않았거나 Shiki 플러그인에 문제가 있습니다.

해결 방법:

astro.config.mjs에서 코드 강조 테마를 설정합니다.

export default defineConfig({
  markdown: {
    shikiConfig: {
      theme: 'github-dark',  // 또는 'dracula', 'nord' 등
    },
  },
});

Blog 템플릿에는 대체로 Shiki가 기본 포함되어 있습니다. 여전히 작동하지 않으면 의존성을 다시 설치해 보세요: rm -rf node_modules && npm install.

문제 6: 개발 서버 시작이 느림

증상: npm run dev를 실행한 뒤 서버가 시작될 때까지 오래 걸립니다.

원인: 글이 너무 많거나 플러그인을 지나치게 많이 설치했습니다.

해결 방법:

  • node_modulespackage-lock.json을 삭제한 뒤 다시 설치합니다.
  • 불필요한 플러그인을 줄입니다.
  • 최신 Astro로 업그레이드합니다(npm install astro@latest).

Astro 5.x는 시작 속도가 크게 개선되었습니다. 아직 4.x를 사용 중이라면 업그레이드를 권장합니다.

많은 문제를 설명했지만 실제로는 대부분 겪지 않을 수도 있습니다. 문제가 생기면 이 장을 다시 살펴보면 빠르게 원인을 찾을 수 있습니다. 저도 이런 문제에 적지 않은 시간을 썼기에 그 경험을 공유합니다.

결론

이 튜토리얼을 끝까지 따라왔다면 축하합니다! 이제 기능이 완전하고 성능이 뛰어나며 바로 사용할 수 있는 Astro 블로그가 생겼습니다. 구현한 내용을 정리해 보겠습니다.

완전한 블로그 시스템: 홈페이지, 글 목록, 상세 페이지, 태그 분류, RSS 구독
SEO 최적화: Meta 태그, Sitemap, 성능 최적화로 콘텐츠의 검색 노출 지원
현대적인 배포: 자동 CI/CD로 코드를 푸시하면 바로 게시되며 서버를 수동 관리할 필요 없음
뛰어난 성능: Lighthouse 95점 이상, 0.8초 첫 화면 로딩으로 우수한 사용자 경험 제공

무엇보다 Astro의 핵심 철학인 콘텐츠 우선, 성능 최우선을 이해했습니다. 이 접근은 블로그뿐 아니라 다른 정적 웹사이트 프로젝트에도 적용할 수 있습니다.

다음으로 무엇을 할 수 있을까요?

지금 바로 실천하기(미루지 마세요):

  • 지금 1시간을 투자해 직접 따라 해 보세요. 진행하면서 이 글을 참고하면 됩니다.
  • 테스트 내용이라도 좋으니 첫 번째 글을 작성해 블로그에 게시해 보세요.
  • 친구나 소셜 미디어에 공유하고 피드백을 모으세요.

고급 기능(천천히 개선하기):

  • 댓글 시스템: Giscus(GitHub Discussions 기반) 또는 Disqus 연동
  • 검색 기능: Algolia DocSearch 또는 Pagefind로 사이트 내 검색 구현
  • 다크 모드: 테마 전환 버튼을 추가해 야간 독자의 이용 편의 개선
  • 읽기 통계: Google Analytics 또는 Plausible(개인정보 보호 중심) 연동
  • 이전 글/다음 글 내비게이션: 글 사이의 연관성 강화

학습 자료(Astro 심화 학습):

  • Astro 공식 문서 - 가장 권위 있는 학습 자료이며 중국어판도 있습니다.
  • Astro 중국어 사이트 - 커뮤니티에서 관리하는 중국어 문서와 자료입니다.
  • Astro Paper - SEO가 잘 구성된 우수한 블로그 템플릿입니다.
  • Astro GitHub 토론 게시판 - 질문하고 경험을 공유할 수 있습니다.

커뮤니티 참여하기(혼자 고민하지 마세요):

  • Astro Discord - 활발한 공식 Discord이며 중국어 채널도 있습니다.
  • GitHub에서 awesome-astro를 검색하면 훌륭한 자료 모음을 많이 찾을 수 있습니다.
  • Astro 커뮤니티의 ‘Showcase’ 채널에 블로그 링크를 공유하고 피드백과 조언을 받아 보세요.

마지막으로 전하고 싶은 말

블로그를 만드는 데 기술은 첫 단계일 뿐이며 더 중요한 것은 꾸준히 글을 쓰는 것입니다. 블로그 프레임워크를 고르는 데 일주일을 쓰고도 글 두 개만 올린 뒤 더 이상 업데이트하지 않는 사람을 많이 봤습니다. Astro는 기술적인 진입 장벽을 최대한 낮춰 줍니다. 이제 남은 것은 꾸준히 콘텐츠를 만들 의지입니다.

실습 중 문제가 생기면 다음 순서로 해결해 보세요.

  1. 먼저 Astro 공식 문서의 ‘Troubleshooting’ 장을 확인합니다.
  2. GitHub 저장소의 Issues에서 키워드를 검색합니다.
  3. Astro Discord에 질문합니다(영어가 중심이지만 중국어 채널도 있습니다).

실수를 두려워하지 마세요. 저도 첫 Astro 블로그를 공개하기까지 사흘 동안 시행착오를 겪었습니다. 하지만 한 번 익히고 나면 블로그 유지보수가 훨씬 쉬워집니다.

이제 명령줄을 열고 Astro 블로그 만들기를 시작해 보세요! 💫

Astro 블로그를 처음부터 만드는 전체 과정

환경 준비부터 배포까지 1시간 안에 완료하는 전체 과정으로, 홈페이지, 글 목록, 태그 분류, RSS 구독, SEO 최적화를 포함합니다.

⏱️ Estimated time: 1 hr

  1. 1

    Step 1: 환경 준비 및 프로젝트 생성

    환경 준비:
    • Node.js 버전이 18 이상인지 확인합니다(node -v 실행).
    • 설치되어 있지 않다면 nodejs.org에서 다운로드합니다.

    프로젝트 생성:
    • npm create astro@latest my-blog를 실행합니다.
    • 템플릿을 선택합니다(Blog 템플릿 권장).
    • TypeScript 사용 여부는 Yes를 권장합니다.
    • 의존성 설치 여부는 Yes를 선택합니다.

    개발 서버 시작:
    • 프로젝트 디렉터리로 이동합니다: cd my-blog
    • 실행합니다: npm run dev
    • http://localhost:4321에 접속해 결과를 확인합니다.
  2. 2

    Step 2: 프로젝트 구조 설정 및 레이아웃 생성

    프로젝트 구조:
    • src/pages: 페이지 파일 저장
    • src/components: 컴포넌트 저장
    • src/layouts: 레이아웃 파일 저장
    • src/content: Markdown 글 저장

    레이아웃 생성:
    • 기본 레이아웃으로 src/layouts/BaseLayout.astro를 생성합니다.
    - HTML 구조, 내비게이션 바, 푸터를 포함합니다.
    • 블로그 글 레이아웃으로 src/layouts/BlogLayout.astro를 생성합니다.
    - BaseLayout을 상속하고 글 관련 스타일을 추가합니다.
  3. 3

    Step 3: 홈페이지 및 글 목록 구현

    홈페이지 생성:
    • src/pages/index.astro에 홈페이지를 만듭니다.
    • 최신 글 목록과 카테고리를 표시합니다.

    글 목록 구현:
    • Astro의 Content Collections 기능을 사용합니다.
    • src/content/posts 디렉터리의 Markdown 파일을 읽습니다.
    • 날짜순으로 정렬해 표시합니다.

    페이지네이션 지원:
    • 글이 많다면 페이지네이션을 구현할 수 있습니다.
    • 페이지마다 글 10개를 표시합니다.

    태그 분류 추가:
    • 글 frontmatter에서 tags를 추출합니다.
    • 태그 클라우드와 분류 페이지를 생성합니다.
  4. 4

    Step 4: 글 상세 페이지 및 RSS 구독 구현

    글 상세 페이지 생성:
    • src/pages/posts/[...slug].astro에 동적 라우트를 만듭니다.
    • slug에 맞는 Markdown 파일을 찾아 렌더링합니다.

    Markdown 렌더링 지원:
    • Astro에 내장된 Markdown 지원 기능을 사용합니다.
    • 코드 강조, 링크, 이미지 등을 자동으로 렌더링합니다.

    RSS 구독 설정:
    • @astrojs/rss 패키지를 설치합니다.
    • src/pages/rss.xml.ts를 생성해 RSS feed를 만듭니다.
    • 모든 글의 제목, 설명, 발행일 등의 정보를 포함합니다.
  5. 5

    Step 5: SEO 최적화 및 배포

    SEO 최적화:
    • 레이아웃 파일에 meta 태그(title, description, og:image 등)를 추가합니다.
    • sitemap.xml을 만들어 사이트맵을 자동 생성합니다.
    • robots.txt를 설정합니다.

    성능 최적화:
    • Astro의 Image 컴포넌트로 이미지를 최적화합니다.
    • 코드 분할을 활성화합니다.
    • 사전 로딩을 설정합니다.

    배포:
    • Vercel을 지원합니다(GitHub 저장소를 연결해 자동 배포).
    • Netlify를 지원합니다(dist 폴더를 끌어다 놓거나 Git 저장소 연결).
    • Cloudflare Pages를 지원합니다(Git 저장소를 연결해 자동 배포).
    • 배포 후 바로 접속할 수 있으며 자동 HTTPS, 글로벌 CDN 가속을 무료로 이용할 수 있습니다.

FAQ

왜 Astro를 선택해야 하나요? 어떤 성능 이점이 있나요?
Astro의 성능 이점:
• 첫 화면 로딩 시간이 3.2초에서 0.8초로 감소
• Lighthouse 점수 100점 달성(기존 WordPress는 65점)
• JavaScript 용량이 280KB에서 20KB 미만으로 감소
• React 프레임워크보다 40% 빠름

Islands 아키텍처의 핵심:
• 콘텐츠를 우선하고 JavaScript는 필요할 때만 로드
• 기본적으로 순수 HTML+CSS 출력
• 명시적으로 상호작용이 필요한 곳에만 JavaScript 로드
• React와 Vue 컴포넌트를 함께 사용 가능

개발 경험: Markdown으로 바로 글을 쓸 수 있어 데이터베이스나 백오피스 관리 시스템을 다룰 필요가 없습니다. VSCode에서 Markdown을 작성해 GitHub에 푸시하면 자동으로 배포됩니다.
Astro 블로그를 처음부터 만드는 구체적인 단계는 무엇인가요?
환경 준비:
• Node.js 버전 18 이상인지 확인
• npm create astro@latest my-blog 실행
• Blog 템플릿과 TypeScript 사용을 선택하고 의존성 설치
• 프로젝트 생성 후 cd my-blog로 프로젝트 디렉터리 이동
• npm run dev로 개발 서버 시작

프로젝트 구조 설정:
• src/pages에 페이지 파일 저장
• src/components에 컴포넌트 저장
• src/layouts에 레이아웃 파일 저장
• src/content에 Markdown 글 저장

레이아웃 생성:
• 기본 레이아웃으로 BaseLayout.astro 생성
• 블로그 글 레이아웃으로 BlogLayout.astro 생성

홈페이지와 글 목록 구현:
• src/pages/index.astro에 홈페이지 생성
• Content Collections로 Markdown 파일 읽기
• 날짜순으로 정렬해 표시하고 페이지네이션과 태그 분류 지원

글 상세 페이지 구현:
• src/pages/posts/[...slug].astro에 동적 라우트 생성
• slug에 맞는 Markdown 파일을 찾아 렌더링

RSS 구독 설정:
• @astrojs/rss 패키지 설치
• rss.xml.ts를 만들어 RSS feed 생성
Astro 블로그의 핵심 기능은 어떻게 구현하나요?
홈페이지 표시:
• src/pages/index.astro에 홈페이지 생성
• 최신 글 목록과 카테고리 표시
• Astro의 Content Collections 기능으로 src/content/posts 디렉터리의 Markdown 파일 읽기

글 목록:
• 날짜순으로 정렬해 표시
• 페이지네이션 지원(페이지마다 글 10개 표시)
• 태그 분류 추가(frontmatter의 tags를 추출해 태그 클라우드와 분류 페이지 생성)

글 상세 페이지:
• src/pages/posts/[...slug].astro에 동적 라우트 생성
• slug에 맞는 Markdown 파일을 찾아 렌더링
• Markdown 렌더링 지원(코드 강조, 링크, 이미지 등을 자동 렌더링)

태그 분류:
• 글 frontmatter에서 tags 추출
• 태그 클라우드와 분류 페이지 생성

RSS 구독:
• @astrojs/rss 패키지 설치
• src/pages/rss.xml.ts를 만들어 RSS feed 생성
• 모든 글의 제목, 설명, 발행일 등의 정보 포함
Astro 블로그의 SEO와 성능은 어떻게 최적화하나요?
SEO 최적화:
• 레이아웃 파일에 meta 태그(title, description, og:image 등) 추가
• sitemap.xml을 만들어 사이트맵 자동 생성
• robots.txt 설정

성능 최적화:
• Astro의 Image 컴포넌트로 이미지 최적화
• 코드 분할 활성화
• 사전 로딩 설정

Astro의 Islands 아키텍처는 기본적으로 성능 최적화를 지원합니다:
• 순수 HTML+CSS를 기본 출력
• 명시적으로 상호작용이 필요한 곳에만 JavaScript 로드
• 기존 React 프레임워크보다 40% 빠르고 JavaScript 용량은 90% 감소
Astro 블로그는 어떻게 배포하나요? 어떤 배포 방법이 있나요?
배포 방법:

Vercel:
• GitHub 저장소를 연결해 자동 배포
• 무료, 자동 HTTPS, 글로벌 CDN 가속

Netlify:
• dist 폴더를 끌어다 놓거나 Git 저장소 연결
• 무료, 자동 HTTPS

Cloudflare Pages:
• Git 저장소를 연결해 자동 배포
• 무료, 글로벌 CDN 가속

배포 단계:
• npm run build를 실행해 dist 폴더 생성
• dist 폴더를 선택한 플랫폼에 배포하거나 GitHub 저장소를 연결해 자동 배포
• 배포 후 바로 접속할 수 있으며 자동 HTTPS와 글로벌 CDN 가속을 무료로 이용
Astro 블로그에 어떤 고급 기능을 추가할 수 있나요?
댓글 시스템:
• Giscus(GitHub Discussions 기반) 또는 Disqus 연동
• 독자가 글 아래에 댓글을 남길 수 있도록 지원

검색 기능:
• Algolia DocSearch 또는 Pagefind로 사이트 내 검색 구현
• 독자가 원하는 콘텐츠를 빠르게 찾도록 지원

다크 모드:
• 테마 전환 버튼을 추가해 야간 독자의 이용 편의 개선

읽기 통계:
• Google Analytics 또는 Plausible(개인정보 보호 중심) 연동
• 글 열람 현황 파악

이 기능들은 해당 Astro 통합 패키지를 설치해 구현할 수 있으며, 설정이 간단하고 성능에 영향을 주지 않습니다.

6분 읽기 · 게시일: 2025년 12월 2일 · 수정일: 2026년 9월 4일

댓글

GitHub로 로그인하여 댓글을 남기세요

Easton BlogEaston Blog