nextjs

· nextjs
Next.js static build + s3 조합에서 라우팅이 안된다?그렇습니다. 아래처럼 next.config 설정하고const nextConfig: NextConfig = { output: "export", // 정적 파일만 trailingSlash: true, images: { unoptimized: true },};빌드하여 s3 에 올리고 CF 붙이면메인 index.html 은 잘 나오는데 라우팅이 안됩니다.클로드쌤과 함께 해결했습니다.CloudFront FunctionsLambda@Edge보다 비용이 저렴한 CloudFront Functions를 사용해 보았습니다.function handler(event) { var request = event.request; var..
· nextjs
🎨 OpenAI Responses API로 이미지 생성 결과 스트리밍 받기OpenAI에서 제공하는 responses API를 이용하면 이제 텍스트 프롬프트로 이미지 생성을 요청할 수 있고, 이를 스트리밍 형식으로 단계별로 수신할 수 있습니다.Next.js와 TanStack Query의 streamedQuery 기능을 활용해 실시간으로 이미지를 받아 UI에 바로 반영하는 방식을 정리합니다.🧩 시스템 구성✅ 주요 기술 스택OpenAI SDK (openai): responses.create를 통해 이미지 스트리밍 요청Next.js Route Handler: 서버 측에서 OpenAI 응답을 ReadableStream으로 래핑TanStack Query (useQuery + streamedQuery): 클라이언..
· nextjs
Q1저는 계속 RSC 와 Next.js 에서 use server 혹은 use client 지시어에 대해 정확히 무슨 일을 하는지 궁금했습니다.단순하게는 use server 를 사용하면 해당 파일은 server side 가 되고, use client 를 사용하면 client side 가 되는 건가? 라고 생각했는데요. Next.js 에서는 아무것도 안쓰면 자동으로 서버 컴포넌트가 되기도 해서 정확한 의미가 궁금했어요.검색을 해보니 use server 는 사용된 모듈 내의 함수를 마치 http 엔드포인트 처럼 만들어서 클라이언트가 사용할 수 있도록 하는 것이고, use client 는 프론트엔드에서 동작할 함수(=컴포넌트)가 데이터를 서버로부터 받을 수 있게하고, 서버에서 렌더링 가능하도록 한다는 것을 알 ..
· nextjs
🧩 문제 정의프로젝트에서 OpenAI의 image edit 기능을 활용한 이미지 생성을 구현하던 중,Amplify 환경에서 API 요청이 504 Gateway Timeout 에러를 반환하는 문제에 직면했습니다.Vercel 배포 환경에서는 요청이 정상적으로 처리되지만,Amplify에서는 Lambda@Edge의 timeout 제한으로 인해 SSR 함수가 29초를 넘기면 강제 종료특히 이미지 생성은 평균 40초 이상 걸리는 작업이라, Amplify 환경에서 실행 불가능🛠 해결 과정1. 구조 분리 (백엔드 역할 Next.js 앱 도입)이미지 생성 로직을 별도의 Next.js 앱에 분리해 ‘백엔드 역할’로 사용클라이언트는 이 앱에 요청을 보내고, 실제 작업은 해당 앱에서 수행2. Polling 방식 적용첫 번..
· nextjs
자주써도 헷갈리는 parallel routes 와 intercepting routes 로기본적인 modal 만드는 법을 정리해보려고 합니다. 1. Parallel RoutesParallel Routes 는 모달을 만들기 위한 기능은 아닙니다.공식문서에 따르면,  Parallel Routes를 사용하면 동일한 레이아웃 내에서 하나 이상의 페이지를 동시에 또는 조건부로 렌더링할 수 있습니다. 대시보드나 피드와 같이 앱의 매우 동적인 섹션에 유용합니다. 예를 들어 대시보드에서 Parallel Routes를 사용하여팀 페이지와 분석 페이지를 동시에 렌더링할 수 있습니다   라고 합니다.만드는 법은 아래처럼 @ 를 붙여서(슬롯이라고 합니다) 폴더를 생성하고 page.tsx 만들면 됩니다.app/ ├─ @moda..
· nextjs
새로 나온 chatGPT-o1 에게 ISR 에 관해 물어봤습니다.revalidatePath 를 통해 데이터가 업데이트 되면 메인페이지를 ISR 하도록 하였습니다.이것이 next.js 에서 적용되는 원리와 과정에 대해 물어보았습니다.GPT 쌤의 답변당신은 Next.js 14 프로젝트에서 App Router를 사용하고 있으며, 라우트 핸들러 내에서 revalidatePath 함수를 구현하여 서버 데이터가 업데이트될 때 Incremental Static Regeneration(ISR)을 트리거했습니다. 이 메커니즘은 전체 재빌드나 수동 개입 없이도 정적으로 생성된 페이지가 최신 데이터를 반영하도록 보장합니다. 이제 이것이 어떻게 작동하는지 원리와 과정을 자세히 살펴보겠습니다.Incremental Static ..
· nextjs
turborepo 로 monorepo 구성하기(with pnpm)1) turbo 테일윈드 템플릿으로 monorepo 생성하기pnpm dlx create-turbo@latest --example with-tailwind2) apps/storybook 에 storybook 설치하기cd appsmkdir storybookcd storybookpnpm dlx storybook@latest init3) packages/ui > packages/shared 로 변경이때 package.json 의 "name" 도 꼭 수정해주어야 함각 app 폴더의 next.config.js 도 수정해주어야 함검색에서 /ui 검색후 나오는 것 모두 /shared 로 변경4) apps 폴더 원하는대로 바꾸고, lock파일 삭제후 다시 ..
· nextjs
turborepo 로 monorepo 구성하기(with pnpm)1) turbo 테일윈드 템플릿으로 monorepo 생성하기pnpm dlx create-turbo@latest --example with-tailwind2) packages/ui 에 storybook 설치하기cd packages/uipnpm dlx storybook@latest init3) apps 폴더 원하는대로 바꾸고, lock파일 삭제후 다시 pnpm installrm pnpm-lock.yamlpnpm install4) apps 폴더 하위의 각 app 폴더의 package.json 수정"scripts": { "dev": "next dev --port 3001", // --port 3001, ---port 3002 등으로 적용 ..
· nextjs
얼러트 모달이 여기저기 필요해서서버, 클라이언트 관계없이 아무데서나 호출해서 쓸 수 있도록아래처럼 사용하고 있었습니다. 그런데 이 방법에 문제가 조금 있었습니다.그냥 써도 무방한 정도였지만 해결해보기로 하였습니다. 문제는 번들 사이즈가 너무 크다는 점 이었습니다.여기저기서 호출 하는 함수인데 무거우면 안될 것이라 판단했습니다.원래 버전원일을 찾아보니 createRoot 를 하기 위해 가져온ReactDom 이 번들사이즈가 132kb 정도로 무거웠습니다.그래서 이것을 제거하고 다른 방법을 사용하기로 했습니다.하지만 그러면 컴포넌트를 사용해서 아무데서나 body에얼러트 모달을 부착할 수가 없었습니다.import CustomAlert from '@/components/organisms/common/CustomA..
· nextjs
Lazy LoadingLazy loading은 Next.js에서 애플리케이션의 초기 로딩 성능을 개선하는 데 도움을 주며, 경로를 렌더링하는 데 필요한 JavaScript의 양을 줄여줍니다. 클라이언트 컴포넌트와 가져온 라이브러리의 로딩을 지연시킬 수 있으며, 필요할 때만 클라이언트 번들에 포함되도록 합니다. 예를 들어, 사용자가 모달을 열려고 클릭할 때까지 모달의 로딩을 지연시킬 수 있습니다. Next.js에서 lazy loading을 구현하는 두 가지 방법이 있습니다:next/dynamic을 사용한 동적 가져오기React.lazy()와 Suspense를 사용기본적으로 서버 컴포넌트는 자동으로 코드 분할이 되며, 스트리밍을 사용하여 서버에서 클라이언트로 UI 조각을 점진적으로 전송할 수 있습니다. La..
· nextjs
state와 UI를 리턴하는 커스텀 훅이 필요해우리에겐 state와 UI(컴포넌트)를 리턴하는 커스텀 훅이 필요합니다. 여기서 state는 전역상태로 관리되면 안되는 상황이므로커스텀 훅에서 리턴하는 state 는 독립적이어야 합니다. 또한 비슷한 UI를 반복적으로 사용해야 하는데 렌더링해야하는데이터종류는 2가지(여정테마/버디즈성향)인 상황입니다. 따라서 커스텀 훅의 리턴은 named export가 될 수 없으므로 객체가 아닌 배열어야 합니다.그렇다면 [컴포넌트, 스테이트] 이렇게 반환하기만 하면 될 것 같습니다.리턴할 컴포넌트먼저 리턴할 컴포넌트를 atoms 레벨에 만들었습니다.type PreferThemeProps = { selectedTheme: string[]; handleThemeCha..
· nextjs
처음 생각한 다이나믹 헤더 의사 코드export default function Page({ params, searchParams,}: { params: { slug: string } searchParams: { [key: string]: string | string[] | undefined }}) { return My Page}Next.js 에서 slug 와 query string 을 가져올 수 있는 위 코드를 사용해서layout.tsx 혹은 page.tsx : (서버컴포넌트 겠죠..? 아마) 에서동적으로 주소에따라 MobileHeader.tsx 컴포넌트로 넘겨주는 props 를 다르게 한다!위 방법은 동적 라우팅에서만 사용가능! 따라서 middleware 설정 추가확인해보니 위 방법은 동적 라우팅..
· nextjs
이미지를 10px 사이즈의 base64 문자열로 변환하는 함수를 작성하기 위해, 먼저 이미지를 불러와서 크기를 조정한 후 base64 형식으로 인코딩해야 합니다. 서버 사이드에서 이미지를 처리하기 위해 sharp 라이브러리를 사용할 수 있습니다. 이를 Next.js API 라우트를 통해 구현할 수 있습니다.다음은 이미지를 10px 사이즈로 변환하고 base64 문자열로 반환하는 API 라우트를 작성하는 방법입니다:1. sharp 라이브러리 설치먼저 sharp 라이브러리를 설치합니다.npm install sharp2. API 라우트 작성src/pages/api/getBase64.ts 파일을 생성하고 다음 코드를 추가합니다:import type { NextApiRequest, NextApiResponse }..
· nextjs
nextjs 14버전에서 pwa 를 셋업하는 방법에 대해 알아보았습니다.1. next-pwa 설치yarn add next-pwa yarn add -D webpack2. next.config.mjs 수정아래와 같이 수정합니다.import withPWAInit from "next-pwa";const withPWA = withPWAInit({ dest: "public",});/** @type {import('next').NextConfig} */const nextConfig = {};export default withPWA(nextConfig);3. 퍼블릭에 manifest.json/public 폴더에 아래와 같이 manifest.json 파일을 작성합니다.{ "name": "My Next.js P..
· nextjs
Step 7. 프로바이더 로그인 버튼 예시"use client";import useAuth from "@/hooks/useAuth";import { showAlert } from "@/lib/openCustomAlert";import { usePathname } from "next/navigation";import { FcGoogle } from "react-icons/fc";function GoogleLogInButton() { const { loginWithProvider } = useAuth(); const pathname = usePathname(); const handleClickGoogle = async () => { if (pathname === "/recove..
· nextjs
여기에서 이어집니다.Step 4. signup & login & logout 라우트 핸들러 작성이메일회원가입 / 로그인 / 로그아웃 용 라우트 핸들러를 작성합니다.회원가입 / 로그인 로그아웃시에는 여기로 요청날리면 됩니다.(3편 콘텍스트api 활용 에서 자세히 설명)// api/auth/signup/route.tsimport { createClient } from "@/supabase/server";import { NextRequest, NextResponse } from "next/server";export async function POST(request: NextRequest) { const data = await request.json(); const name = data.name a..
· nextjs
수파베이스를 사용한 인증/인가를 구현하면서 애를 많이 먹었습니다.특히나 자료들이 대부분 조금 오래된 버전들이 많아서 더욱 힘들었습니다. 예를들어 나름 1년~6개월 전쯤에 작성된 자료임에도 Page 라우터를 사용하는 자료라거나,혹은 use client 를 사용해서 처리해야만 하는 클라이언트 사이드 로직을 알려주는 경우가 많았습니다. 하지만 공식홈페이지 자료에는 불친절하긴해도 어찌저찌 방법이 거의 다 나와있긴했고이를 참고하여 이메일 로그인, 비밀번호 찾기, 소셜로그인(깃헙, 구글, 카카오)을 구현하는데 성공했습니다. 과정을 복기하며 하나하나 메모해두려고 합니다.Step 1. Supabase clientNext.js 에서 Supabase 를 최적으로 사용하기 위해서는,이제Supabase Client 를 두 가..
· nextjs
오늘부터 next.js 공식문서를 하나씩 파헤쳐보려고 합니다.시작으로, 제가 잘 몰랐던 Template.tsx 부터 해보겠습니다.template.js템플릿 파일은 각 하위 레이아웃 또는 페이지를 래핑한다는 점에서 레이아웃과 유사합니다.경로 전체에서 지속적으로 상태를 유지하는 레이아웃과 달리 템플릿은 탐색 시(on Navigation) 각 하위 레이아웃에 대해 새 인스턴스를 만듭니다.export default function Template({ children }: { children: React.ReactNode }) { return {children}}   흔하지는 않지만 원하는 경우 레이아웃 대신 템플릿을 선택할 수 있습니다.사용 효과(예: 페이지 조회 수 기록) 및 사용 상태(예: 페이지별 피드백..
· nextjs
라이브러리 같은거 쓰는데 걍 import 했더니 window is not defined 어쩌구 할 때 하라는대로 import 했는데 안될 때 window가 없다고 해서 client 컴포넌트에서 import 했더니 브라우저에서는 되는데 서버측 window is not ... 일 때 1번 해결책 : next/dynamic "use client" import dynamic from 'next/dynamic'; const 작명 = dynamic(() => import('위치'), {ssr: false}); // 아래쪽에서 // 이런식으로 쓰면됨 그래도 안될 때 2번 해결책 useEffect(() => { import('위치') .then((module) => { const 작명 = module().default..
· nextjs
link 사용시 주의점 1. import 할 것 import Link from 'next/link' export default function Page() { return Dashboard } 2. 뒤로가기 안되게 하고 싶으면(history에 안쌓음) replace 추가 import Link from 'next/link' export default function Page() { return ( Dashboard ) } 3. scroll 기억하고 싶으면 scroll={false} 추가: 기본값(true)은 최상단으로 올라감 import Link from 'next/link' export default function Page() { return ( Dashboard ) } 4. 뷰포트에 보이는 요소중 L..
adminisme
'nextjs' 카테고리의 글 목록