묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨Next.js 까보기: "쓸 줄 아는 개발자"에서 "알고 쓰는 개발자"로
필터옵션이 많은 페이지에서도 서버 fetch를 사용하는게 맞을까요??
강의에서 말씀해준 내용도 그렇고, next 공식문서에서도 서버 fetch를 권장하고 있지만필터옵션이 다수 포진된 페이지에서도 서버 fetch를 해야할까 의문점이 듭니다. 필터 버튼 하나 누를때마다 다시 fetch 해야하니까 route.push나 replace 할 수 밖에 없는데 이게 과연 좋은 방법인가 의구심이 듭니다.리액트 쿼리를 사용하는게 더 나을지, 서버 fetch를 사용하는게 나은지 선생님의 의견이 궁금합니다. 추가로 window.history.replaceState webAPI를 사용하면 단순 url만 변경하고 페이지 로드나 컴포넌트 리렌더링은 일어나지 않는걸로 알고 있는데요. 근데 리액트 쿼리로 클라이언트 fetch 할 땐 window.history.replaceState 로 url만 변경해도 다시 fetch가 되더라구요?? 어떤 원리로 동작하게 되는지 궁금합니다!
-
미해결한 입 크기로 잘라먹는 Next.js(v15)
백엔드 서버를 배포했는데, 어쩔 땐 정상적으로 로딩이 되는데 어쩔 땐 500 에러가 발생합니다
무엇이 문제일까요? 간헐적으로 새로고침을 하면 제대로 로딩이 됐다 안 됐다 하는데 그로 인해 당연히 한입북스에 백엔드 데이터도 못 불러오는 거 같습니다!
-
미해결Next.js 완벽 마스터 (v15): 노션 기반 개발자 블로그 만들기 (with 커서AI)
A
안
-
해결됨[풀스택 완성] Supabase로 웹사이트 3개 클론하기 (Next.js 14)
강의 code 올려논 github 있나요 ?
있으면 url 좀 알려주세요.
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
GRAPHQL 활용 과제
과제 10 진행하고 있습니다."수정을 하기 위해서는 글을 입력할때 설정하였던 비밀번호를 입력받아야 합니다."이런 조건이 있던데 비밀번호는 어디에 저장되는 건가요?
-
미해결Next + React Query로 SNS 서비스 만들기
서버 fetch suspense 로 감싸고 새로고침 시 잠시 빈 화면이 노출된 후 fallback ui가 노출됩니다.
autoexport default function Weekday() { return ( <Suspense fallback={<WeekdayBannerLoading />}> <WeekdayMiniBanner /> </Suspense> ); }export default function WeekdayMiniBanner() { const { banners } = use(getBanners( params )); if (banners.length === 0) return null; return ( <div className={cn('wrapper')}> <WeekdaySwiper data={banners} /> </div> ); }이런 식으로 코드를 짰는데요. 해당 페이지를 새로고침하면 초기엔 컨텐츠영역 아무것도 노출되지않다가 잠깐 fallback ui가 노출되고 fetch가 완료되면 컨텐츠를 노출시킵니다. suspense는 promise가 pending 중일 때 promise를 catch해서 fallback ui 를 노출시키는걸로 알고 있는데 왜 새로고침 시 페이지 초기로드단계에선 빈화면이 노출되는지 궁금합니다... 아님 제가 잘못 설계한 걸까요..?? 리액트 공식문서 suspense 예시 코드에선 버튼 누르자마자 바로 fallback ui를 노출시키는데 말이죠... 참고로 WeekdaySwiper 내부는 react swiper로 구성되어있습니다! (클라이언트 컴포넌트)
-
미해결Next.js 까보기: "쓸 줄 아는 개발자"에서 "알고 쓰는 개발자"로
서버 fetch suspense 로 감싸고 새로고침 시 잠시 빈 화면이 노출된 후 fallback ui가 노출됩니다.
export default function Weekday() { return ( <Suspense fallback={<WeekdayBannerLoading />}> <WeekdayMiniBanner /> </Suspense> ); }export default function WeekdayMiniBanner() { const { banners } = use(getBanners( params )); if (banners.length === 0) return null; return ( <div className={cn('wrapper')}> <WeekdaySwiper data={banners} /> </div> ); }이런 식으로 코드를 짰는데요. 해당 페이지를 새로고침하면 초기엔 컨텐츠영역 아무것도 노출되지않다가 잠깐 fallback ui가 노출되고 fetch가 완료되면 컨텐츠를 노출시킵니다. suspense는 promise가 pending 중일 때 promise를 catch해서 fallback ui 를 노출시키는걸로 알고 있는데 왜 새로고침 시 페이지 초기로드단계에선 빈화면이 노출되는지 궁금합니다... 아님 제가 잘못 설계한 걸까요..?? 리액트 공식문서 suspense 예시 코드에선 버튼 누르자마자 바로 fallback ui를 노출시키는데 말이죠... 참고로 WeekdaySwiper 내부는 react swiper로 구성되어있습니다! (클라이언트 컴포넌트)
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
7-1 서버 액션에서 Page 컴포넌트 옮기는 과정 질문드립니다.
안녕하세요 정환님 강의 잘 보고 있습니다.이번 섹션 8. 7.1) 서버 액션을 소개합니다. 에서 궁금한게 있는데요 이전에 섹션 4. App Router에서 32. 3.2)페이지 라우팅 설정하기 강의에서 "URL 파라미터나 searchParams, Query String 같은 값은 Promise로부터 꺼내써야 되는걸로 알고 그렇게 변경해서 사용했습니다." const BookDatail = async ({ bookId }: { bookId: string }) => { const response = await fetch( `${process.env.NEXT_PUBLIC_API_SERVER_URL}/book/${bookId}` ); // ... 생략 /* 저의 code */ export default async function Page({ params, }: { params: Promise<{ id: string }>; }) { const { id } = await params; return ( <div> <BookDatail bookId={id} /> </div> ); } /* 정환님이 강의해서 사용한 code */ export default function Page({ params, }: { params: {id:string}; }) { return ( <div> <BookDatail bookId={params.id} /> </div> ); }경로 app/book/[id]/page.tsx URL 파라미터 값을 Promise로부터 꺼내와야 된다는 업데이트 강의 부분을 보고 한거라서 이게 맞는지 헷갈리네요 강의 전체를 아직 수강 전 인데 헷갈릴까봐 질문드립니다.
-
미해결제로베이스부터 배우는 웹개발의 개념과 바이브 코딩
블로그 애드센스 인증 실패문제
Ads.txt 스니펫을 시도하고 ads.txt 를 퍼블릭에 추가해주고 업로드했는데도 자꾸 아래 문구가 뜨네요 사이트를 확인할 수 없습니다사이트를 확인할 수 없습니다. 사이트의 변경사항이 게시되었고 Google 애드센스 크롤러가 이를 액세스할 수 있는지 확인하세요. 문제가 계속 발생하는 경우 다른 방법을 시도해 보세요.
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
노란색 경고줄
노란색 경고줄이 안뜨는데 뜨게 하는 방법이 무엇인가요??
-
미해결한 입 크기로 잘라먹는 Next.js(v15)
백엔드 서버 연결 중 npm run seed 에러 확인 부탁드립니다ㅜ
백엔드 서버 연결 환경 세팅 중 npm run seed를 CLI창에 입력하였는데 오류가 발생되어 확인 부탁드립니다. 깃허브 레포지토리 링크 : https://github.com/hyunji1117/onebite-books-server-main
-
미해결제로베이스부터 배우는 웹개발의 개념과 바이브 코딩
클로드 3.5 or 4.0 유료 구매를 해야 하나요^^
안녕하세요.Cursor 실습에 사용하기 위해서 클로드 3.5 or 4.0을 사용하기 위해서 유료로 구매를 하고강의를 따라 가야하는지 문의 드리오니 답변 부탁드립니다.클로드 3.5도 유료로 되어 있군요. ㅠㅠ그리고, 혹시 클로드 3.5 무료로 실습 할 수 있는 방법이 있으면 갈켜주세요.감사합니다.
-
미해결Next + React Query로 SNS 서비스 만들기
template.tsx 내 서버fetch 응답값과 클라이언트 컴포넌트 상태값 싱크가 맞지 않는 이슈
아래 코드와 같이 template.tsx에서 서버fetch 후 사용처인 클라이언트 컴포넌트로 props 넘겨주도록 세팅해놓았습니다. //template.tsx 자식 컴포넌트 export default async function Sidebar() { const { isSucceed, body } = await getUserGetInfo(params); return ( <SidebarLayout> <GiftIcon isNewGift={!!body?.info.new_gift} /> 'use client' export default function GiftIcon({ isNewGift }: { isNewGift: boolean }) { const { onClose } = useModal('SIDEBAR'); return ( <Link className={isNewGift ? cn(st['active']) : ''} /// <Icon type="Present" title="선물함" w={25} h={25} /> 이 상태에서 next 페이지 이동 시 서버fetch는 리렌더링 되는것을 확인했는데이상하게 클라이언트는 리렌더링이 되지 않습니다. 즉 서버 응답값은 상태가 바뀌어도 클라이언트 상태값은 바뀌지 않더라구요... 왜 이런걸까요ㅠㅠㅠ
-
해결됨Next.js 까보기: "쓸 줄 아는 개발자"에서 "알고 쓰는 개발자"로
template.tsx 에서 서버 fetch 후 클라이언트 컴포넌트로 넘겨주면 싱크가 맞는 이유
아래 코드와 같이 template.tsx에서 서버fetch 후 사용처인 클라이언트 컴포넌트로 props 넘겨주도록 세팅해놓았습니다. //template.tsx 자식 컴포넌트 export default async function Sidebar() { const { isSucceed, body } = await getUserGetInfo(params); return ( <SidebarLayout> <GiftIcon isNewGift={!!body?.info.new_gift} /> 'use client' export default function GiftIcon({ isNewGift }: { isNewGift: boolean }) { const { onClose } = useModal('SIDEBAR'); return ( <Link className={isNewGift ? cn(st['active']) : ''} /// <Icon type="Present" title="선물함" w={25} h={25} /> 이 상태에서 next 페이지 이동 시 서버fetch는 리렌더링 되는것을 확인했는데이상하게 클라이언트는 리렌더링이 되지 않습니다. 즉 서버 응답값은 상태가 바뀌어도 클라이언트 상태값은 바뀌지 않더라구요... 왜 이런걸까요ㅠㅠㅠ
-
미해결바이브 코딩: Next.js + FastAPI + Faster-Whisper로 음성 메모 앱 만들기
5. Faster-Whisper 설치 및 기본 사용법 실습중 에러가 계속납니다
코드 따라해서 했는데 파일을 업로드해도 무한로딩이 됩니다에러내용:OMP: Error #15: Initializing libiomp5.dylib, but found libiomp5.dylib already initialized.OMP: Hint This means that multiple copies of the OpenMP runtime have been linked into the program. That is dangerous, since it can degrade performance or cause incorrect results. The best thing to do is to ensure that only a single OpenMP runtime is linked into the process, e.g. by avoiding static linking of the OpenMP runtime in any library. As an unsafe, unsupported, undocumented workaround you can set the environment variable KMP_DUPLICATE_LIB_OK=TRUE to allow the program to continue to execute, but that may cause crashes or silently produce incorrect results. For more information, please see http://www.intel.com/software/products/support/.어떻게 해야하나요?
-
해결됨Next.js 까보기: "쓸 줄 아는 개발자"에서 "알고 쓰는 개발자"로
layout 컴포넌트 내 클라이언트 컴포넌트
안녕하세요~ 강의 내용 중 궁금한게 있는데요 layout에선 usepathname, usesearchparams 와 같은 값에 접근할 수 없기 때문에 'use client' 지시어를 활용해 클라이언트 컴포넌트를 통해 해당 값에 접근해야한다 라고 말씀해주셨는데 이 개념은 단순 서버 컴포넌트와 클라이언트 컴포넌트에 따른 차이점과 동일한 의미 아닌가요??next.js 자체가 서버컴포넌트 일 경우 usepathname, usesearchparams 와 같은 훅을 사용할 수 없는데 Page.tsx 컴포넌트도 마찬가지 아닌가요?? 'layout에선' usepathname, usesearchparams 와 같은 값에 접근할 수 없기 때문에 'use client' 지시어를 활용해 클라이언트 컴포넌트를 통해 해당 값에 접근해야한다. 라는 말씀이 Page.tsx 에서의 사용법과 어떤 차이점이 있는지 잘 이해가 가질 않습니다... 아 참고로next 클라이언트 페이지 라우팅 시 layout영역은 리렌더링 되지 않고 page.tsx 영역만 렌더링된다라는 partial rendering 개념은 이해했습니다. 강의랑 유튜브 항상 잘 보고있습니다. 양질의 영상 제공해주셔서 감사합니다!
-
미해결제로베이스부터 배우는 웹개발의 개념과 바이브 코딩
Kakao AdFit, Stripe 내용
광고 삽입법 (Google AdSense, Kakao AdFit)결제 연동 (Toss Payments, Stripe)강의 소개에 Kakao AdFit, Stripe 언급도 있었는데 강의를 쭉 봤을 땐 내용이 없더라구요. 혹시 제가 놓친 부분이 있을까요?
-
미해결Next.js 15로 완성하는 실전 YouTube 클론 개발
drizzle-zod로 변환한 videoUpdateSchema를 z.infer로 추론하면 타입에러가 나타납니다.
'BuildSchema<"update", { id: PgColumn<{ name: "id"; tableName: "videos"; dataType: "string"; columnType: "PgUUID"; data: string; driverParam: string; notNull: true; hasDefault: true; isPrimaryKey: true; isAutoincrement: false; ... 4 more ...; generated: undefined; }, {}, {}>; ... 15 more ...; updatedAt: PgColumn<...>...' 형식이 'ZodType<any, any, any>' 제약 조건을 만족하지 않습니다. 'ZodObject<{ id: ZodOptional<ZodUUID>; title: ZodOptional<ZodString>; description: ZodOptional<ZodNullable<ZodString>>; ... 13 more ...; updatedAt: ZodOptional<...>; }, { ...; }>' 형식에 'ZodType<any, any, any>' 형식의 type, parse, getType, getOrReturnCtx 외 7개 속성이 없습니다.라는 에러 문구가 코드 에디터에 나타납니다.
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
181. [02-04] setState의 원리 질문
setIsActive(false) 콘솔에는 찍히는데 backgroundColor: yellow가 gray로는 바뀌고 none으로 하면 바뀌지 않는 이유가 무엇일까요?!
-
해결됨인프런 클론코딩 Part 1: Next.js와 NestJS로 시작하는 실전 프로젝트
[auth][error] JWTSessionError: Read more at...
강의25. [BE] 백엔드 Auth Guard 구현 시작. Auth Guard로 유저 아이디 가져오는 부분 작업타임라인 19:55여기까지는 정상적으로 진행됩니다.쿠키에서 "authjs.session-token" 확인이 가능합니다. import NextAuth from "next-auth"; import { PrismaAdapter } from "@auth/prisma-adapter"; import { prisma } from "@/prisma"; import CredentialsProvider from "next-auth/providers/credentials"; import { comparePassword } from "@/lib/password-utils"; import * as jwt from "jsonwebtoken"; import { JWT } from "next-auth/jwt"; export const { handlers, auth, signIn, signOut } = NextAuth({ useSecureCookies: process.env.NODE_ENV === "production", trustHost: true, adapter: PrismaAdapter(prisma), secret: process.env.AUTH_SECRET, providers: [ CredentialsProvider({ name: "credentials", credentials: { email: { label: "이메일", type: "email", placeholder: "이메일 입력", }, password: { label: "비밀번호", type: "password", }, }, async authorize(credentials) { // 1. 모든 값들이 정상적으로 들어왔는가? if (!credentials || !credentials.email || !credentials.password) { throw new Error("이메일과 비밀번호를 입력해주세요."); } // 2. DB에서 유저를 찾기 const user = await prisma.user.findUnique({ where: { email: credentials.email as string, }, }); if (!user) { throw new Error("존재하지 않는 이메일입니다."); } // 3. 비밀번호 일치 여부 확인 const passwordMatch = comparePassword( credentials.password as string, user.hashedPassword as string ); if (!passwordMatch) { throw new Error("비밀번호가 일치하지 않습니다."); } return user; }, }), ], session: { strategy: "jwt", }, jwt: { encode: async ({ token, secret }) => { return jwt.sign(token as jwt.JwtPayload, secret as string); }, decode: async ({ token, secret }) => { return jwt.verify(token as string, secret as string) as JWT; }, }, pages: {}, callbacks: {}, }); FE 추가분/frontend/auth.ts// ... 중략 import * as jwt from "jsonwebtoken"; import { JWT } from "next-auth/jwt"; export const { handlers, auth, signIn, signOut } = NextAuth({ // ...중략 jwt: { encode: async ({ token, secret }) => { return jwt.sign(token as jwt.JwtPayload, secret as string); }, decode: async ({ token, secret }) => { return jwt.verify(token as string, secret as string) as JWT; }, }, // ... 중략 }) pnpm add jsonwebtoken pnpm add -D @types/jsonwebtoken GET /api/auth/csrf 200 in 47ms POST /api/auth/callback/credentials? 200 in 114ms[auth][error] JWTSessionError: Read more at https://errors.authjs.dev#jwtsessionerror[auth][cause]: Error: The edge runtime does not support Node.js 'crypto' module. Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime at Object.get (C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\_6e5868ec._.js:62:41) at C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\node_modules__pnpm_d2b00409._.js:8647:62 at getSecret (C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\node_modules__pnpm_d2b00409._.js:8630:20) at push.[project]/node_modules/.pnpm/jsonwebtoken@9.0.2/node_modules/jsonwebtoken/verify.js [middleware-edge] (ecmascript).module.exports (C:\Users\svx32\OneDrive\바 탕 화면\v5\frontend\.next\server\edge\chunks\node_modules__pnpm_d2b00409._.js:8633:12) at Object.decode (C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\[root-of-the-server]__273b5c62._.js:137:233) at session (C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\fdcd2_@auth_core_ec592ae5._.js:4516:39) at AuthInternal (C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\fdcd2_@auth_core_ec592ae5._.js:5123:269) at async Auth (C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\fdcd2_@auth_core_ec592ae5._.js:5379:34) at async handleAuth (C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\node_modules__pnpm_d2b00409._.js:3913:29) at async C:\Users\svx32\OneDrive\바탕 화면\v5\frontend\.next\server\edge\chunks\_6e5868ec._.js:12505:20[auth][details]: {} GET / 200 in 62ms--- 이 오류 메시지는 애플리케이션이 Edge Runtime 환경에서 Node.js의 crypto 모듈을 사용하려고 시도할 때 발생하는 JWTSessionError 입니다. 오류 상세 설명 JWTSessionError: 이는 JWT(JSON Web Token) 세션 관리 중에 문제가 발생했음을 나타냅니다. JWT는 웹 애플리케이션에서 사용자 세션을 처리하는 일반적인 방법입니다.The edge runtime does not support Node.js 'crypto' module.: 이 부분이 핵심 문제입니다. Edge Runtime (예: Next.js Edge Functions 또는 Middleware)은 빠르고 가볍게 설계된 환경입니다. 따라서 모든 Node.js API를 지원하지 않으며, 특히 암호화, 해싱, 디지털 서명 등에 사용되는 crypto 모듈을 포함하지 않습니다. JWT 작업은 이 crypto 모듈에 크게 의존합니다.스택 트레이스 분석: 오류 스택 트레이스를 보면 jsonwebtoken 패키지(특히 verify 작업 중)에서 crypto 모듈에 접근하려고 시도하며, 이 과정이 @auth/core(일반적으로 Auth.js 라이브러리)에서 호출됩니다. 이는 JWT 유효성 검사 프로세스가 crypto 모듈의 부재로 인해 실패하고 있음을 명확히 보여줍니다.간단히 말해, 애플리케이션이 Edge Runtime이라는 제한된 서버리스 환경에서 JWT 유효성 검사(보안 관련 작업)를 수행하려고 하지만, 이 환경에는 해당 작업을 위한 필수 도구(crypto 모듈)가 없기 때문에 오류가 발생하는 것입니다. 해결 방법 (일반적인 접근) 이 문제를 해결하기 위해서는 주로 다음 방법들을 고려할 수 있습니다:JWT 관련 작업을 Edge Runtime 외부로 이동: JWT 유효성 검사와 같이 crypto 모듈이 필요한 작업은 Edge Runtime이 아닌 일반적인 Node.js 서버 환경(예: Next.js의 표준 API 라우트)에서 수행하도록 변경해야 합니다.인증 라이브러리 설정 변경: 사용하고 있는 인증 라이브러리(Auth.js)의 세션 전략을 변경하여 Edge Runtime 컨텍스트에서 crypto 모듈에 의존하지 않도록 구성해야 합니다. 예를 들어, JWT 기반 세션 대신 데이터베이스 세션과 같은 다른 세션 관리 방식을 고려할 수 있습니다.AUTH_SECRET 확인: 직접적인 원인은 아니지만, AUTH_SECRET 환경 변수가 올바르게 설정되어 있고, 사용 중인 환경에 맞게 JWT를 안전하게 처리하는지 확인하는 것도 중요합니다.어떻게 해결해야하나요??