Skip to content
Go back

Astro를 사용하여 GitHub Pages 사이트 만들기

Published:  at  12:36 PM

Astro, Themes, GitHub Pages 배포, 그리고 Plugins

astro.build

Table of contents

Open Table of contents

Astro

https://docs.astro.build/

올인원 웹 프레임워크
Content driven (Islands), UI agnostic, Server first, Zero JS, ..
v5.9.2 (2024.12-)

Install

Requirements

npm create astro@latest
> Need to install the following packages: create-astro@4.12.1
> Where should we create your new project?
> How would you like to start your new project?
> -- A basic, helpful starter project | Use blog template | Use docs (Starlight) template | Use minimal (empty) template
> Install dependencies?
> Initialize a new git repository?

npm run dev
> http://localhost:4321

Instructions

├── public/
├── src/
   ├── components/
   ├── content/
   ├── layouts/
   ├── styles/
│   └── pages/
│       └── index.astro
├── astro.config.mjs
├── package-lock.json
├── package.json
└── tsconfig.json

Deploy to GitHub Pages

https://docs.astro.build/en/guides/deploy/github/

  1. Set the site and base
import { defineConfig } from "astro/config";

export default defineConfig({
  site: "https://username.github.io", // 혹은 사용자 정의 도메인
  base: "/", // 루트 혹은 username.github.io 경우 비워둔다, 루트를 별도로 처리해야 할 경우 '/repository'
});astro.config.mjs
  1. Configure GitHub Actions

https://github.com/withastro/action/blob/main/README.mdrepository/ Settings/ Code and automaiton - Pages/ Build and deployment/ GitHub Actions → .github/workflows/deploy.yml

name: Deploy to GitHub Pages

on:
  # Trigger the workflow every time you push to the `main` branch
  # Using a different branch name? Replace `main` with your branch’s name
  push:
    branches: [main]
  # Allows you to run this workflow manually from the Actions tab on GitHub.
  workflow_dispatch:

# Allow this job to clone the repo and create a page deployment
permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout your repository using git
        uses: actions/checkout@v4
      - name: Install, build, and upload your site output
        uses: withastro/action@v4
        # with:
        # path: . # The root location of your Astro project inside the repository. (optional)
        # node-version: 22 # The specific version of Node that should be used to build your site. Defaults to 22. (optional)
        # package-manager: pnpm@latest # The Node package manager that should be used to install dependencies and build your site. Automatically detected based on your lockfile. (optional)

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4.github/workflows/deploy.yml

Creating pages and posts

Astro는 파일 기반 라우팅을 한다. src/pages/ 의 각 파일은 사이트의 endpoint가 된다.

├── src/
│   └── pages/
│       ├── index.astro
│       ├── about.astro
│       └── posts/
│           └── post.md

.astro 파일

.md 파일

---
title:
description:
pubDate: YYYY-MM-DD
author:
image:
  url:
  alt:
tags: []
---

<!--- 이하 본문 --->posts/post.md

Themes

다음 테마들을 추천한다.

Astro Paper

https://github.com/satnaing/astro-paper
Stack : astro, tailwindcss, astro-icon, dayjs, lodash.kebabcase, satori, sharp, pagefind

Install

pnpm create astro@latest --template satnaing/astro-paper
# or
git clone https://github.com/satnaing/astro-paper.git
cd astro-paper
pnpm install

# Warning
# Ignored build scripts: esbuild, sharp.
# Run "pnpm approve-builds" to pick which dependencies should be allowed to run scripts.
pnpm approve-builds

pnpm run dev

Instructions

astro-paper/
├── .github/workflows/
       └── ci.yml
├── public/
├── src/
   ├── assets/
   └── icons/
   └── images/
   ├── components/
   ├── data/blog/
       └── some-posts.md
   ├── layouts/
   ├── pages/
│     └── index.astro
   ├── styles/
   ├── utils/
   ├── config.ts
   ├── constants.ts
   └── content.config.ts
├── astro.config.mjs
├── package-lock.json
├── package.json
└── tsconfig.json

Set the SITE and SOCIALS

export const SITE = {
  website: "https://username.github.io", // replace this with your deployed domain
  author: "Full Name",
  profile: "https://github.com/username",
  desc: "",
  title: "",
  ogImage: "", // public/og.jpg
  lightAndDarkMode: true,
  postPerIndex: 4, // view in Home - Recent section
  postPerPage: 10,
  scheduledPostMargin: 15 * 60 * 1000, // 15 minutes
  showArchives: true,
  showBackButton: true, // show back button in post detail
  editPost: {
    enabled: true, // 게시물 제목아래 편집링크 제공 여부
    text: "Suggest Changes",
    url: "https://github.com/owner/username.github.io/edit/main/",
  },
  dynamicOgImage: true,
  lang: "ko", // html lang code. Set this empty and default will be "en"
  timezone: "Asia/Seoul", // Default global timezone (IANA format) https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
} as const;src/config.ts
export const SOCIALS = [
  {
    name: "Github",
    href: "https://github.com/username",
    linkTitle: ` ${SITE.title} on Github`,
    icon: IconGitHub,
  },
  // ...
] as const;src/constants.ts

Configure GitHub Actions

name: CI

on:
  pull_request:
    types:
      - opened
      - edited
      - synchronize
      - reopened
  workflow_call:

jobs:
  build:
    name: Code standards & build
    runs-on: ubuntu-latest
    timeout-minutes: 3

    strategy:
      matrix:
        node-version: [22]

    steps:
      - name: "☁️ Checkout repository"
        uses: actions/checkout@v4
      - name: "📦 Install pnpm"
        uses: pnpm/action-setup@v4
        with:
          version: 10
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: "pnpm"
      - name: "📦 Install dependencies"
        run: pnpm install
      - name: "🔎 Lint code"
        run: pnpm run lint
      - name: "📝 Checking code format"
        run: pnpm run format:check
      - name: "🚀 Build the project"
        run: pnpm run build.github/workflows/ci.yml

https://github.com/withastro/action/blob/main/README.md

# ...
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout your repository using git
        uses: actions/checkout@v4
      - name: Install, build, and upload your site output
        uses: withastro/action@v4
        with:
          # path: . # The root location of your Astro project inside the repository. (optional)
          # node-version: 22 # The specific version of Node that should be used to build your site. Defaults to 22. (optional)
          package-manager: pnpm@latest # The Node package manager that should be used to install dependencies and build your site. Automatically detected based on your lockfile. (optional)
# ....github/workflows/deploy.yml

Creating posts

src/data/blog/

---
title:
description:
pubDate: YYYY-MM-DDThh:mm:ss+09 # (ISO 8601형식 중 구분자(-,:)와 ss 필수)
modDatetime:
slug:
author:
tags: []
draft:
image:
  url:
  alt:
ogImage:
featured:
canonicalURL:
hideEditPost:
timezone: # 콘텐츠내 시간대 -- new Date().toISOString()
---

<!--- 이하 본문 --->

Update template and dependencies

# Updating AstroPaper template
# 새로운 원격(테마)저장소를 추가하고 업데이트용 로컬브랜치로 이동
git remote add astro-paper https://github.com/satnaing/astro-paper.git
git remote -v
git checkout -b update/astro-paper

# 다음 두가지 방식이 있다.
# 1. merge 방식: 단 한 번의 충돌 해결을 선호할 때 (git config pull.rebase false)
# 원격 테마의 최신 변경사항을 update/astro-paper 브랜치로 가져올 때, 모든 변경사항을 하나의 병합커밋(merge commit)으로 통합한다.
# 다만, 히스토리에 병합 커밋이 자주 생성되어 git log가 다소 복잡해 보일 수 있다.
git pull astro-paper main
# fatal: refusing to merge unrelated histories (최초 병합시)
git pull astro-paper main --allow-unrelated-histories
# fatal: Need to specify how to reconcile divergent branches. Need to specify --no-rebase
git pull astro-paper main --no-rebase
# conflict 해결 후 커밋
git status
> On branch update/astro-paper
> You have unmerged paths.
> Unmerged paths:
>   both modified: src/styles/base.css
git add .
git commit -m "Resolve merge conflicts with astro-paper main update"

# 2. rebase + squash: 깔끔한 선형 히스토리를 선호할 때 (git config pull.rebase true)
# 원격 브랜치의 최신 커밋들 위에 로컬 커밋들을 하나씩 순서대로 적용하므로, 충돌은 여러 번일 수 있다.
# 여기에 단 한 번의 충돌 해결을 원한다면, 다음 명령으로 update/astro-paper의 모든 로컬 커밋들을 미리 하나의 커밋으로 합쳐둔(squash)후 진행한다. (main 커밋들은 영향받지 않는다!)
git reset --soft $(git rev-list --max-parents=0 HEAD) && git commit --amend --no-edit

git pull astro-paper main --rebase
# 각 커밋별 변경사항 확인, conflict 해결 후 계속
> Auto-merging .github/workflows/ci.yml
> Auto-merging src/constants.ts
> CONFLICT (content): Merge conflict in src/constants.ts
> error: could not apply 4daa336... Initial commit
> hint: Resolve all conflicts manually, mark them as resolved with
> hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
> hint: You can instead skip this commit: run "git rebase --skip".
> hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
> hint: Disable this message with "git config set advice.mergeConflict false"
git add .
git rebase --continue

> fatal: no rebase in progress
git status
> On branch update/astro-paper
> nothing to commit, working tree clean

# 로컬 main으로 병합
git checkout main
git pull origin main
git merge update/astro-paper
git status
> On branch main
> Your branch is ahead of 'origin/main' by 40 commits.
>  (use "git push" to publish your local commits)
git push origin main

# 원격(테마)저장소, 업데이트용 로컬브랜치 삭제
git branch -d update/astro-paper
git remote remove astro-paper
git remote -v

Updating Package Dependencies — 테마의 package, lock을 우선시 하자.

# Updating Package Dependencies
npm install -g npm-check-updates
ncu
ncu -i --target patch
ncu -i

Issues

  1. 외부 링크에 대해 내부 링크로 처리되는 문제
<body>
  <slot />

  <script is:inline data-astro-rerun>
    /* 외부링크를 _blank로 열도록 처리 */
    // DOM이 로드된 후에 스크립트가 실행되도록 보장하고
    // astro 파일이라 그런가 -- (X) DOMContentLoaded, (O) data-astro-rerun | astro:page-load
    // document.addEventListener("astro:page-load", () => {
    // 문서 내의 모든 <a> 태그(링크)를 배열로 변환
    Array.from(document.links)
      .filter(link => {
        const href = link.getAttribute("href");
        // 현재 호스트네임과 다르면서 호스트네임이 비어있지 않고,
        // href가 없거나 '#'으로 시작하는 앵커 링크가 아닌 경우만 필터링
        return (
          link.hostname !== window.location.hostname &&
          link.hostname !== "" &&
          (!href || !href.startsWith("#"))
        );
      })
      // 필터링된 각 외부 링크에 대해 다음 작업을 수행
      .forEach(link => {
        link.target = "_blank";
        link.rel = "noopener noreferrer"; // 보안 취약점(Tabnabbing)을 방지
      });
    // });
  </script>
</body>src/layouts/Layout.astro

Plugins

Giscus

https://github.com/giscus/giscus/blob/main/README.ko.md
오픈 소스 또는 내부 프로젝트에 대한 커뮤니티를 위한 협업 커뮤니케이션 포럼

<Layout {...layoutProps}>
  <main>
    <ShareLinks />

    <!-- Comments 스크립트 추가 -->
    <script
      src="https://giscus.app/client.js"
      data-repo="owner/username.github.io"
      data-repo-id="R_kgDOOrIEX.."
      data-category="Comments"
      data-category-id="DIC_kwDOOrIEXs4.."
      data-mapping="pathname"
      data-strict="1"
      data-reactions-enabled="1"
      data-emit-metadata="1"
      data-input-position="bottom"
      data-theme="preferred_color_scheme"
      data-lang="ko"
      data-loading="lazy"
      crossorigin="anonymous"
      async></script>
  </main>
  <Footer />
</Layout>src/layouts/PostDetails.astro

ref.


Suggest Changes
Share this post on:

Next Post
Jekyll을 사용하여 GitHub Pages 사이트 만들기