블로그를 만들게 된 이유
블로그를 위해 Astro를 선택 한 이유
왜 블로그를 만들게 되었나요?
블로그를 쓸수 있는 플랫폼은 정말 다양합니다. tistory, github pages, 미디엄, 네이버블로그, velog, 워드프레스 다양한 플랫폼이 있습니다.
컨텐츠를 쓸수있는곳은 많지만, 한곳에 정착하기에는 어려움이 있었습니다. 저는 마크다운으로 쓰는것을 좋아했으며, 언젠가는 플랫폼이 닫힐때 내 글들은 사라질수도 있겠구나 라는 생각을 한편으로 하고있기도 했어요.
그러다가 obsidan을 만나고, 오프라인에서 마크다운으로 글을 쓸수있고, 그 쓰는것도 다른플랫폼에 뒤지지 않는 편리성을 가짐을 느꼈고, 이 obsidan을 기반으로 블로그를 만들수 있다면 좋겠다는 생각을 했습니다.
프론트엔드를 주로 하는 개발자다보니, 직접 css를 사용할수있고 필요한곳에 js를 삽입할수 있으면 좋겠다고 생각했습니다.
포트폴리오용으로도 좋고, 삽입한 코드를 실행시켜 보여줄수 있는것도 좋다고 생각했습니다.
그래서 만들게된 블로그가 astro 기반의 블로그입니다.
nextjs도 쓸수 있었을텐데 왜 astro로 개발하게 되었을까요?
nextjs대신 astro를 선택한 근본적인 이유로는 두가지가 있었습니다.
- 블로그에 최적화된 프레임워크
- canvas, js 등 새로운 기술을 웹에서 즉시 보여줄수 있는 기능
번들사이즈의 크기차이 zero javascript
Nextjs의 초기 번들사이즈는 React Runtime + hydration 로직만으로 40kb는 기본입니다 반면에 astro는 정말 필요한 javascript만 보내기 떄문에 랜딩페이지같은경우 5kb 이하로도 가능합니다.
정적 HTML 생성
Nextjs SSG도 정적파일을 생성하지만, hydration을 위한 javascript 코드가 여전히 포함됩니다. 검색엔진 크롤러에게는 불필요한 overhead라고 생각되었습니다.
astro는 완전한 HTML을 생성하기 때문에 크롤링봇 입장에서는 깔끔한 HTML만 보여집니다
특정 페이지 혹은 포스트에만 필요한 js를 포함시켜 번들링이 가능하다
블로그 컨텐츠에 리액트가 필요할지, 아니면 gsap같은 애니메이션이 필요하냐에 따라 import를 달리할수 있습니다 그 페이지가 로드될때는 필요한만큼의 js를 가져올수 있습니다. react에만 종속된게 아닌, vue 혹은 새로운 기술에 대해서도 필요할때 js를 포함시켜서 페이지를 로드할수 있기 때문에 확장면에서도 좋은 기회를 제공합니다.
많은 욕심이 들어간 블로그라고 생각합니다
- 마크다운으로 글을 쓸수 있어야한다
- offline에 글을 작성하기 용이해야한다
- SEO에 최적이어야 한다
- 다양한 JS코드를 보여줄수 있어야한다
이런것들을 충족시켜야 하다보니 astro를 고려하게 되었습니다.
Obsidian으로 컨텐츠를 어떻게 배포하나요?
github actions를 활용해 컨텐츠를 배포합니다 저는 제 글이 github에 올릴때마다 다른사람들에게 보여지는걸 원하지는 않았습니다.
일과 블로그는 분리되어야 한다고 생각했기 때문에 하나의 레포에서 글을 올림으로서 회사나 협업하는 누군가가 글을 매일 알림으로 보길 원하지는 않았어요.
그래서 떠오른 생각은 github pages는 퍼블릭으로, obsidian content는 private로 올리자 라는 아이디어에서 시작했습니다.
github pages는 pksung1.github.io 레포에 그대로 astro를 활용해 작업했습니다 그리고 src/content/blog 는 [[github submodules]]로 작업하였습니다
[submodule "src/content/blog"]
path = src/content/blog
url = git@github.com:pksung1/obsidian-content.git
새로 만든 obsidian-content 레포에는 obsidian vault를 그대로 올려두었습니다.
개인적으로 작업하는 _ 로 시작하는 폴더는 블로그글로 인식하지 않도록 하였습니다 daily 노트나 template 같은건 블로그글로 보여지지는 않아도 괜찮으니까요.
import { glob } from 'astro/loaders';
import { defineCollection, z } from 'astro:content';
const blogCollection = defineCollection({
loader: glob({ pattern: ['**/*.md', '!_*/**'] }),
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.date(),
updatedDate: z.date().optional(),
heroImage: z.string().optional(),
tags: z.array(z.string()).default([]),
}),
});
export const collections = {
'blog': blogCollection,
};
그래서 astro에는 pattern으로 인식할수 있도록 loader 코드를 작성해두었습니다.
다른 private 레포를 가져오기
github actions에서 기본으로 발급되는 GITHUB_TOKEN은 제 다른 레포에 접근하지 못합니다. 그래서 personal github token이 필요합니다.
직접 classic으로 토큰을 생성하고 아래와같이 checkout할때 해당 토큰을 이용할수 있도록 workflow 를 수정하였습니다
- name: Checkout your repository using git
uses: actions/checkout@v4
with:
submodules: true
token: ${{ secrets.PAT_TOKEN }}
이 코드로 인해 서브모듈은 함께 불러와지게 됩니다.
컨텐츠를 배포할때마다 블로그 재배포하기
이제 이부분을 해결해야하는데, 생각보다 간단합니다.
repository_dispatch를 활용하면특정 레포에서 전달한 이벤트를 다른 레포에서 수신할수 있습니다.
astro 블로그 actions에 하단 코드를 추가합니다.
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 ]
repository_dispatch:
types: [post-publish] # 포스트글 퍼블리싱이 되었을때 디스패치를 처리하도록
# Allows you to run this workflow manually from the Actions tab on GitHub.
workflow_dispatch:
obisidan-content에는 아래 yaml을 추가합니다