{"id":39608128,"url":"https://github.com/umsungjun/new_portfolio_next","last_synced_at":"2026-01-18T08:01:46.278Z","repository":{"id":283786284,"uuid":"918164131","full_name":"umsungjun/new_portfolio_next","owner":"umsungjun","description":"😗 Next Portfolio는 기존에 React로 개발된 New Portfolio(https://github.com/umsungjun/new_portfolio) 를 Next.js로 마이그레이션한 프로젝트입니다.  약 3년간의 실무 경험을 통해 습득한 기술들을 바탕으로 제작되었으며, 데이터 관리와 렌더링 최적화에 중점을 두었습니다. 실무에서 접할 수 없었던 Next.js를 학습하고 활용하기 위한 목적으로 개발했습니다.","archived":false,"fork":false,"pushed_at":"2026-01-15T07:16:37.000Z","size":304,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-15T14:17:05.872Z","etag":null,"topics":["next","portfolio","react","umsungjun"],"latest_commit_sha":null,"homepage":"https://next-umsungjun.vercel.app/ko/home","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/umsungjun.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-17T11:26:47.000Z","updated_at":"2026-01-15T07:16:31.000Z","dependencies_parsed_at":"2025-03-22T07:23:31.516Z","dependency_job_id":"3a9058d0-c734-4e93-9132-2a0732a0b3a7","html_url":"https://github.com/umsungjun/new_portfolio_next","commit_stats":null,"previous_names":["umsungjun/new_portfolio_next"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/umsungjun/new_portfolio_next","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umsungjun%2Fnew_portfolio_next","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umsungjun%2Fnew_portfolio_next/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umsungjun%2Fnew_portfolio_next/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umsungjun%2Fnew_portfolio_next/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/umsungjun","download_url":"https://codeload.github.com/umsungjun/new_portfolio_next/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umsungjun%2Fnew_portfolio_next/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28533746,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T00:39:45.795Z","status":"online","status_checked_at":"2026-01-18T02:00:07.578Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["next","portfolio","react","umsungjun"],"created_at":"2026-01-18T08:01:45.546Z","updated_at":"2026-01-18T08:01:46.254Z","avatar_url":"https://github.com/umsungjun.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Next Portfolio(https://next-umsungjun.vercel.app/ko/home)\n\n\u003cimg width=\"100%\" src=\"https://drive.google.com/thumbnail?id=1JoY3oZxH1lDNXwItJ6c13rG-H1HU4LYH\u0026sz=w1000\"/\u003e\n\n## 프로젝트 소개\n\nNext Portfolio는 기존에 React로 개발된 New Portfolio(https://github.com/umsungjun/new_portfolio)를 Next.js로 마이그레이션한 프로젝트입니다.\n\n2년간의 실무 경험을 통해 습득한 기술들을 바탕으로 제작되었으며, 데이터 관리와 렌더링 최적화에 중점을 두었습니다. 실무에서 접할 수 없었던 Next.js를 학습하고 활용하기 위한 목적으로 개발했습니다.\n\n## 기존 React 프로젝트와의 차이점 및 개선점\n\n```\n1. 데이터 관리 방식 개선\n\n기존에는 Google Cloud Sheet를 데이터 저장소처럼 활용하였으나, 실무 경험을 쌓으며 데이터베이스를 활용한 관리 방식이 더 효율적이라는 점을 깨달았습니다.\n\n이를 개선하기 위해 Supabase를 도입하여 Question, Answer 테이블을 생성하고 Prisma ORM을 활용하여 데이터 조작을 보다 쉽게 수행할 수 있도록 했습니다.\n\n2. CSR과 SSR의 적절한 조합\n\nSSR(Server-Side Rendering): 웹 화면의 좌측 소개 영역은 SSR을 사용하여 빠르게 렌더링되도록 구현하였습니다.\n\nCSR(Client-Side Rendering): 우측 질문-답변 UI(채팅 영역)은 CSR 방식을 적용하여 사용자와의 상호작용이 원활하도록 구성했습니다.\n\n3. Next.js 활용 극대화\n\n기존 React 프로젝트는 CSR 중심이었지만, Next.js의 서버 컴포넌트 기능을 활용하여 성능과 SEO를 최적화하였습니다.\n\nNext.js의 Metadata API를 사용하여 각 언어별 title, description, keywords를 동적으로 설정하여 SEO를 강화했습니다.\n```\n\n### 프로젝트 사용 기술\n\n```\nNext.js(15.1.4), TypeScript, Tailwind CSS, Zustand, next-intl, Prisma, Supabase\n```\n\n### 폴더 구조\n\n```\n├─ app\n│  ├─ [locale]\n│  │  ├─ home\n│  │  │  ├─ @chat\n│  │  │  │  ├─ _components\n│  │  │  │  │  ├─ answer.tsx\n│  │  │  │  │  ├─ question.tsx\n│  │  │  │  │  └─ selectQuestion.tsx\n│  │  │  │  ├─ _lib\n│  │  │  │  │  └─ constants.ts\n│  │  │  │  ├─ body.tsx\n│  │  │  │  ├─ header.tsx\n│  │  │  │  └─ page.tsx\n│  │  │  ├─ @side\n│  │  │  │  ├─ _components\n│  │  │  │  │  ├─ contactInfo.tsx\n│  │  │  │  │  └─ profileSwiper.tsx\n│  │  │  │  └─ page.tsx\n│  │  │  └─ layout.tsx\n│  │  └─ layout.tsx\n│  ├─ api\n│  │  ├─ answer\n│  │  │  └─ route.ts\n│  │  └─ question\n│  │     └─ route.ts\n│  └─ globals.css\n├─ components\n│  └─ swrProvider.tsx\n├─ i18n\n│  ├─ loadSpreadSheet.js\n│  ├─ request.ts\n│  └─ routing.ts\n├─ lib\n│  ├─ client\n│  │  ├─ constants.ts\n│  │  └─ type.ts\n│  └─ server\n│     └─ prisma.ts\n├─ messages\n│  ├─ en.json\n│  └─ ko.json\n├─ middleware.ts\n├─ package.json\n├─ postcss.config.mjs\n├─ prisma\n│  ├─ migrations\n│  │  └─ migration_lock.toml\n│  └─ schema.prisma\n├─ public\n│  ├─ favicon.ico\n│  └─ robots.txt\n├─ store\n│  └─ useChatStore.ts\n├─ tailwind.config.ts\n└─ tsconfig.json\n```\n\n## 커밋 컨벤션\n\n```\nFeat : 새로운 기능을 추가하는 경우\nFix : 버그를 고친경우\nDocs : 문서를 수정한 경우\nStyle : 코드 포맷 변경, 세미콜론 누락, 코드 수정이 없는경우\nRefactor : 코드 리펙토링\nTest : 테스트 코드 추가 및 리팩토링\nChore : 빌드 업무 수정, 패키지 매니저 수정\nDesign : CSS 등 UI 디자인 변경\nRename : 파일명(or 폴더명) 수정\nRemove : 코드(파일) 삭제\n```\n\n## 트러블 슈팅 기록\n\n### 1. Hydration failed 오류 해결\n\n```\n문제점: .env 파일에서 PUBLIC_PHONE_NUMBER를 사용했을 때 Hydration 오류 발생\n\n해결 방법\n- 기존 `.env` 파일에 있었던 상수 `PUBLIC_PHONE_NUMBER`를 `NEXT_PUBLIC_PHONE_NUMBER`로 변경하여 해결\n- `NEXT_PUBLIC_PHONE_NUMBER`는 클라이언트에서 접근 가능, `PHONE_NUMBER`는 서버 컴포넌트에서 접근 가능\n\n📌 참고 문서: [Next.js Hydration Error] (https://nextjs.org/docs/messages/react-hydration-error)\n```\n\n### 2. next-intl의 getTranslations 작동 오류 해결\n\n```\n문제점: 서버 컴포넌트에서 getTranslations() 작동 오류\n\n해결 방법\n- getTranslations()에 locale 값을 명시적으로 전달\n\nexport default async function Side({ params }: SideProps) {\n  const { locale } = await params;\n  const t = await getTranslations({ locale });\n}\n\n```\n\n### 3. Next.js 15.2.3에서 generateMetadata 함수 작동 오류 해결\n\n```\n문제점: Next.js 15.2.3에서 generateMetadata 함수가 호출되지 않는 문제 발생\n\n해결 방법\n- Next.js 버전을 15.1.4로 다운그레이드하여 정상 동작 확인\n- Next.js의 Metadata API를 활용하여 SEO 메타데이터를 동적으로 생성하도록 수정\n- 다국어 지원을 위해 locale에 따라 title, description, keywords 등을 설정\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumsungjun%2Fnew_portfolio_next","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fumsungjun%2Fnew_portfolio_next","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumsungjun%2Fnew_portfolio_next/lists"}