6-keem
Gallery
About
© Powered by 6-keem

Github Readme 배지 만들기 🪪

Frontend
2024년 12월 22일
3분

On this page
  • 들어가며
  • 제작 과정
  • 1. 디렉터리 구조 및 역할
  • 2. 코드 구조
  • 3. 배포 및 확인

이전 글이 없습니다
다음 포스트
Next.js Type error: Type '*' does not satisfy the constraint '**'. Types of property 'params' are incompatible.
배지
Next.js 15.1.0 버전을 기준으로 작성되었습니다.

들어가며

3학년 2학기가 끝나고 나니, 그동안 진행했던 프로젝트들을 정리하고 싶다는 생각이 들었다.
우연히 다른 사람들의 GitHub Readme를 보게 되었는데, 내 Readme와 비교되어 초라하게 느껴졌다.
특히, Medium, Velog 등 블로그의 최신 글을 표시하는 이미지를 활용한 Readme가 눈에 띄었다.
나도 비슷한 기능을 구현하고 싶어졌다. 나의 미적 감각은 처참하기에 다음의 디자인을 적극 참고하였다.

Velog-포스트로-Github를-꾸며보자

제작 과정

1. 디렉터리 구조 및 역할

├── app
│   ├── about
│   ├── api
│   │   └── badge
│   │       ├── Badge.tsx
│   │       └── route.ts
│   ├── blog
├── components
├── config
├── data
├── gallery
├── hooks
├── lib
Next.js에서 간단한 API 개발이 가능하다!

각 파일의 역할은 다음과 같다.

  • route.ts : endpoint (컨트롤러의 역할)
  • Badge.tsx : 블로그 최신글의 정보가 담긴 이미지(svg) 파일 반환

2. 코드 구조

route.ts

import { NextRequest } from "next/server";
import BlogBadge from "./Badge";
 
export async function GET(request: NextRequest) {
    const { searchParams } = new URL(request.url);
    const width = searchParams.get("width") ?? "450";
    const height = searchParams.get("height") ?? "130";
 
    const badge = await BlogBadge({ width, height });
    return new Response(badge, {
        status: 200,
        headers: {
            "Content-Type": "image/svg+xml",
        },
    });
}

Content-Type 을 설정하지 않으면 이미지가 출력되지 않으니 주의

Badge.tsx

export default async function BlogBadge({
    width,
    height,
}: {
    width: string;
    height: string;
}) {
    const post = (await getPostList())[0];
    let currentX = 22;
 
    const mappedRects = post.tags
        .map((item, index) => {
            ...
 
            const svgFragment = `
        <g class="tag-group" style="animation: fadeIn 0.5s ease-out ${
            index * 0.1
        }s both;">
            ... 태그
        </g>
      `;
            currentX += rectWidth + gapBetweenRects;
            return svgFragment;
        })
        .join("");
 
    // SVG 반환
    return `
    <svg
     ... 세부 내용
    </svg>
  `;
}

디자인은 자세히 다루지 않겠지만 여기에서 전체 코드를 볼 수 있다.


3. 배포 및 확인

*/api/badge?width=360&height=130으로 접속하면 이미지가 잘 반환되는 것을 볼 수 있다.

<a target="_blacnk" href="블로그 주소">
    <img src="*/api/badge?width=360&height=130" />
</a>

이로써 게시글 업로드 시 Github Readme에 최신글이 표시될 것이다. 🤩