프로젝트 29

[맛길] Zustand + sessionStorage로 맛집 리스트 캐싱하기

Zustand와 sessionStorage로 데이터를 캐싱하게 된 계기 맛길을 배포 후 지인들에게 피드백을 요청했습니다. 가장 많이 받은 피드백이 페이지를 이동할 때마다 이전 데이터가 사라져 불편하다는 내용이었습니다.피드백을 바탕으로 생각해보니 아래와 같은 문제가 있을 수 있을 것 같습니다.페이지 전환이나 새로고침 시 기존 데이터를 다시 불러오기 위해 불필요한 API 요청이 발생API 응답이 길어질 경우, UX(사용자 경험) 저하길 찾기 기능에서 prop drilling 발생이 문제를 해결하기 위해 Zustand를 도입해 맛집 리스트와 위치 정보를 전역으로 관리하고, 맛집 리스트를 sessionStorage에 저장해 불필요한 API 호출을 줄이기로 했습니다.Zustand를 선택한 이유 : 상태 관리 라이..

[맛길] 접근성, SEO 개선

사이트 배포 후 lighthouse를 이용해 접근성, SEO를 체크했습니다.분명 접근성과 SEO를 고려하면서 작업했다고 생각했는데 결과가 92점이네요. 낮은 점수는 아니지만 완성도 높은 서비스를 만들기 위해 개선 작업을 해보겠습니다.접근성 개선위 사진은 접근성 테스트에서 통과하지 못한 요소들입니다. 차례대로 하나씩 살펴보면서 수정해 보겠습니다. 1️⃣ 텍스트 & 배경색 명암비텍스트 색과 배경 색의 대비는 저시력자나 고령자도 인식할 수 있도록  4.5:1 이상이어야 한다고 합니다.기존 버튼의 경우 배경색이 #059669, 텍스트가 #FFFFFF로 3.7:1입니다. 명암비 접근성 테스트 사이트를 이용해 접근성을 준수하도록 수정했습니다. 2️⃣ 버튼 터치 영역 수정버튼의 크기를 W3C에서 권장하는 터치 영역 ..

[맛길] 안드로이드(AOS) 위치 정보(Geolocation API) 지연 문제 해결

사이트 배포 후 모바일 디바이스(AOS, IOS)에서 아래 브라우저들을 통해 길 찾기 기능을 테스트했습니다.Chrome (IOS, AOS)Naver 앱 (IOS, AOS)카카오 인 앱 브라우저 (IOS, AOS)Firefox (IOS, AOS)Edge (IOS, AOS)Opera (IOS, AOS)safari (IOS)삼성 인터넷(AOS)IOS에서는 길 찾기가 정상적으로 동작하는 반면, AOS( Android OS)의 경우 경로를 받기까지 매우 오래 걸리는 문제가 발생했습니다. 테스트에 사용한 기종이 오래된 갤럭시 S10이라는 의심이 들어, 가장 최신 기종인 갤럭시 s25로도 테스트해봤지만 결과는 같았습니다. 혹시 서버에서 응답이 늦게 오는건 아닐까 하는 생각에 Vercel의 로그도 확인해 봤지만, 실행..

[맛길] Naver Directions API를 이용한 길 찾기 기능 개발

현재 Naver Map API를 이용해 맛집 가게의 지도를 불러오고 마커를 찍는 기능까지 구현했습니다. 지인들에게 테스트와 피드백을 부탁했습니다. 모바일 디바이스에서 터치로 화면을 움직일 때 지도가 움직여서 불편하다.맛길 서비스 내에 지도에서 길 찾기 기능을 사용할 수 있으면 좋을 것 같다.첫 번째 피드백을 토대로 테스트 해보니 모바일 디바이스에서 지도 영역의 인터랙션 때문에 화면을 스크롤하기가 불편했습니다. 이 부분은 사용자 입장에서 부정적인 경험이라고 생각해 인터랙션 옵션을 제거하는 방법으로 수정했습니다. 두 번째 피드백인 길찾기 기능입니다.사용자 입장에서 생각해보니 맛길 서비스에서 맛집의 위치를 찾아도 별도의 길 찾기 서비스를 이용해야 한다는 점에서 번거로울 것 같습니다. 이런 불편함을 제거하고 사..

[Coworkers] 접근 권한 관련 이슈 해결

멤버 관련 테스트 작업을 진행하던 중 이슈를 발견했습니다.🚨 문제 상황 팀의 멤버가 아닌 유저가 팀 페이지(/[teamid])와 할 일 목록(/[teamid]/[tasklist])에 접근 및 추가/수정/삭제를 할 수 있습니다. 팀의 멤버가 아닌 사용자가 해당 페이지에 접근할 수 있는 유일한 방법은 URL을 직접 입력하는 것입니다. 하지만 URL을 직접 입력하여 접근한 후 수정/삭제 등의 작업을 시도할 가능성도 존재합니다. 이를 방지하기 위해 추가적인 보안 조치가 필요해 보입니다. 요청/추가/수정/삭제 동작이 모두 가능한 것을 보니, 서버에서 API 요청 시 팀 멤버 여부를 확인하는 로직이 없는 것 같습니다. 프론트엔드에서 처리할 수 있는 방법을 생각해 본 결과 아래 두 가지 정도가 있을 것 같습니다. ..

[맛길] Naver Map API를 이용한 맛집 지도 추가

오늘은 맛집 상세 페이지에 지도를 추가해 보겠습니다. 지도는 Naver Map API를 이용해 볼 계획입니다. 0️⃣ Naver Map API 선택 이유Naver Map API v3 특징  프레임워크에 의존하지 않고 독립적으로 동작하기 때문에 불필요한 의존성을 최소화할 수 있고,  React & Next.js로 제작된 맛길 프로젝트에 적합할 것 같아 선택했습니다. DOM 처리 및 웹 브라우저 호환 코드를 내장하고 있어 크로스 브라우징 이슈를 최소화하면서 손쉽게 지도 기능을 구현할 수 있을 거라 생각해 선택했습니다.별도의 CSS를 필요로 하지 않도록 설계된 내용을 보고, 개발 부담을 줄일 수 있을 것 같아서 선택했습니다. 모바일 환경에서도 최적화된 성능을 제공하기 때문에 별도의 최적화 작업이 필요하지 않아..

[Coworkers] IOS 이미지 업로드 이슈

🚨 문제 상황팀 수정하기 관련해서 IOS 기기에서 이미지가 업로드되지 않는 이슈가 생겼습니다.이미지 업로드 관련 코드uploadImage.tsimport postImage from '@/app/lib/image/postImage';const uploadImage = async (profile: FileList) => { if (!profile || !(profile[0] instanceof File)) return null; const formData = new FormData(); formData.append('image', profile[0]); const { url } = await postImage(formData); return url;};export default uploadImag..

[Coworkers] 리팩토링

오늘은 1차 배포 테스트가 얼마 남지 않아서 리팩토링을 진행해 보겠습니다.계획 없이 리팩토링을 진행하면 결과물의 퀄리티가 떨어질 수 있을 것 같아, 작업을 시작하기 전에 어떤 방향으로 개선할 것인지 계획을 세워보겠습니다.리팩토링 중점 사항1️⃣ 가독성변수와 함수를 이름만 보고도 어떤 역할을 하는지 알 수 있도록 의미 있게 수정하겠습니다.불필요한 로직이나 변수를 제거해 코드를 간결하게 유지하겠습니다.코드를 간결하게 유지하기 위해 컴포넌트를 기능별로 적절히 분리하겠습니다.2️⃣ 재사용성특정 UI가 반복적으로 사용되는 경우 컴포넌트화해 재사용하겠습니다.자주 사용되는 로직이나 기능은 커스텀 훅, 유틸 함수로 분리해 재사용하겠습니다. 3️⃣ 유지보수성컴포넌트와 함수가 하나의 책임만 갖도록 수정하겠습니다. SOLI..

[맛길] 상세 페이지 - Youtube 영상 추가

오늘은 상세 페이지를 작업할 건데요.처음 기획 당시 페이지 상단에 맛집 소개 Youtube 영상을 띄우기로 했었네요.. 어떤 방법이 있는지 찾아볼게요👀✨ 영상 추가 방법1️⃣ 기본 태그 이용  유튜브 영상에 자체적으로 퍼가기 기능을 제공하고 있네요😀 iframe의 src를 보니 프로젝트에서 사용하는 데이터의 videoId를 embed/ 뒤에 추가하면 될 것 같아요. 2️⃣ react-youtube 라이브러리 및 Youtube API 사용 사용법을 보니 videoId 부분에 Youtube API에서 요청을 통해 받아온 videoId를 넣어주면 되는 것 같아요. 원래라면 Youtube API를 연동해서 아래와 같은 과정을 거치겠죠🤔  서버에서 Youtube로 API key를 포함한 데이터 요청 유튜브..

[맛길] 동적 라우팅(Dynamic Routing) 적용

🚨 문제 상황프로젝트를 진행하면서 Youtube 채널을 추가하면서 점점 불편함을 느끼게 되었어요. 위의 이미지처럼 채널이 추가될 때마다 /app 폴더 하위에 폴더가 점점 늘어나 구조가 너무 복잡해지게 되더라고요😭 왜 채널(라우트 페이지)마다 폴더를 만드는지 궁금하실 수 있겠네요🤔Next.js가 파일 시스템 기반의 라우터를 사용하여 폴더를 경로 정의에 사용하기 때문이에요. 위 예시를 보시면 /app 폴더 하위의 폴더 이름이 경로로 사용되고 있어요. /{channel}/page.tsximport axios from '@/app/lib/instance';import ListContainer from '@/app/components/lists/ListContainer';async function page(..