클라이언트에서 서버에 데이터를 보낼 때 보통 FormData 객체를 사용합니다.nextjs에서 서버 액션으로 전달할 때, 폼에 이미지도 포함되어있어서, formData로 전달하는 방법을 택했습니다. 하지만 formData는 중첩 구조를 지원하지 않기 때문에, (html form 기반이라 key=value flat 구조만 지원)formData.append()를 통해 직접 하나씩 넣어줘야하는 불편함이 있었습니다. 그래서 중첩된 객체를 재귀적으로 FormData로 변환하고, 다시 파싱하는 로직을 구현하였습니다.언제 FormData를 사용하고, 언제 JSON을 쓰는가?파일이 없고 일반 데이터만 있다면 → JSON.stringify(data)가 기본 선택입니다.파일이 포함되어 있거나, 서버에서 multipart..
전체 글
🐠 🐟 🐡 블로그 이전 합니다 (https://velog.io/@lee_yani)Supabase에서 이미지를 업로드할 땐 storage를 활용하게 되는데,저는 중첩된 storage 구조에서 파일을 삭제하는 과정에서 꽤나 헤맸습니다... 😢 만약 유저가 삭제 되었을 때나 포스트가 삭제되었을 때 처럼해당 유저나 포스트에 해당하는 상위 폴더만 삭제하면 하위 이미지들도 함께 삭제될 줄 알았습니다. 예를 들면 이런 식입니다. const { error: storageDeleteError } = await supabase.storage .from('places') .remove([`${user.id}/${logId}/${placeId}`]); 하지만 결과는 아무일도 일어나지 않았습니다... 왜 그럴까?Supabase Storage는 사실상 "폴더"라는 개념이 없습니다.실제로는 경로 기반의 평..
프로젝트에서는 사용자가 여러 장의 이미지를 업로드할 수 있는 기능을 제공하고 있습니다.특히 메인 서비스인 로그 작성 기능에서는 썸네일 이미지 외에도 여러 개의 장소를 입력할 수 있고,장소 1개당 최소 1장, 최대 8장의 이미지를 업로드할 수 있도록 제한하고 있습니다. 하지만 서비스 개선 과정에서 다음과 같은 문제가 발생하기 시작했습니다이미지 수가 많아질수록 업로드 시간이 길어지고, (장소 당 업로드 가능 이미지 수를 3장 -> 최대 8장으로 확대)서버 응답이 느려지거나 실패하는 경우가 생기고, 특히 모바일 환경에서는 체감 성능이 확 떨어지는 문제가 있었습니다 이러한 문제를 해결하기 위해, 기존의 서버 액션 기반 업로드 방식에서 -> signed URL 기반의 클라이언트 직접 업로드 방식으로 전환하였습니..
React 기반으로 개발해오던 기존 프로젝트를 Next.js로 마이그레이션하면서,메인 서비스 기능인 로그 등록/수정을 담당하는 폼 구조를 전면적으로 개편하게 되었습니다. 기존 폼은 다중 필드, 중첩 필드, 단일/다중 이미지 업로드 기능을 모두 포함하고 있었고,이를 Controller로 각각 직접 관리하는 구조였습니다. 처음에는 명확한 책임 분리를 위해 나름대로 잘 구성했다고 생각했지만,실제로는 복잡하고 가독성이 떨어지는 구조로 이어졌습니다. 기존 구조 : 전역 상태 + Controller + 이미지 관리 커스텀 훅기존에는 react-hook-form의 defaultValues에 장소 필드를 빈 배열로 두고,사용자가 선택한 장소 데이터는 전역 상태로 따로 관리했습니다. (로그 작성 페이지 전에 카카오맵으로..
TypeScript ExercisesA set of interactive TypeScript exercisestypescript-exercises.github.io Exercise 1 더보기export type User = { name : string; age : number; occupation : string;};export const users: User[] = [ { name: 'Max Mustermann', age: 25, occupation: 'Chimney sweep' }, { name: 'Kate Müller', age: 23, occupation: 'Astronaut' }];e..
오늘은 웹 개발 중 자주 마주치는 HTTP 요청 관련 개념들을 정리했다.Axios를 사용하면서 겪은 궁금증들을 하나씩 정리하며 개념을 명확히 했다. HTTP 요청 헤더: Authorization과 쿠키 인증Access Token은 보통 Authorization: Bearer 헤더에 넣어 전송.하지만 토큰을 쿠키에 저장하는 경우, 별도로 Authorization 헤더는 비어있거나, 없어도 된다. 브라우저가 자동으로 쿠키를 보내주기 때문. (withCredentials: true를 설정하면 쿠키가 자동 전송)Refresh Token은 보통 별도의 엔드포인트(/auth/refresh)를 호출해서 새로운 Access Token을 받아오는 방식으로 사용. Referer를 활용한 뒤로 가기 처리찾아보던 중에 R..
배경메인서비스에서 사용자가 이미지를 자주 추가하거나 변경할 수 있습니다.이미지를 입력받으면, 각 이미지에 대해 signed URL을 요청하고, 최적화(용량 압축 및 리사이징) 과정을 거친 후 서버에 업로드합니다. 따라서, 서버에 올리기 전에 이미지 최적화가 필요하고, 업로드한 이미지를 즉시 미리보기로 확인할 수 있어야합니다. 문제 상황처음에는 react-image-file-resizer를 사용하여 이미지 최적화를 구현했습니다. (기존에 팀원이 적용했었습니다.) 하지만 이 라이브러리는 리사이징 중심이기 때문에 반드시 파일 이미지의 width, height를 명시해야합니다.프로필 이미지와 같이 크기가 항상 동일한 파일은 상관이 없지만, 아래와 같이 이미지 파일의 크기가 제각각인 경우에는 이미지 크기를 명확..
1. next-pwa 설치 next-pwaNext.js with PWA, powered by workbox.. Latest version: 5.6.0, last published: 3 years ago. Start using next-pwa in your project by running `npm i next-pwa`. There are 85 other projects in the npm registry using next-pwa.www.npmjs.com 2. mainfest 추가public 폴더에 넣으면 됩니다. PWA Manifest Generator | ProgressierThis free tool allows you create an app manifestprogressier.com{ "sho..