묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Next + React Query로 SNS 서비스 만들기
Nextjs dev모드 오류
nextjs dev모드로 실행하다가 코드 저장하면 자꾸 서버 다운될 때도 많고, 코드 새로 수정해도 반영 안 될 때가 있어서, 서버 껐다 키는 경우가 빈번한데.. 이런거 해결하는 방법 없나요.. 제 컴퓨터에서는 nextjs가 너무 무거워서 리로드 하는 시간도 너무 오래 걸려서요 ㅠㅠ
-
미해결Next + React Query로 SNS 서비스 만들기
쿠키 로그인 방식에 대한 궁금한 점이 있습니다!
서버 배포후 제공해주는 쿠키의 domain이, .naver.com이고, 만약 로컬호스트로 개발 할 경우 localhost의 도메인을 갖게되어, 둘의 도메인이 달라, 쿠키가 담기지 않는 경우가 발생합니다. 모든 통신 요청을 서버와 직접 진행 할 경우, .naver.com의 쿠키로, 모든것이 공유가 가능하니, 정상적으로 접근이 가능한 것 같은데이제 간혹, 라우트 핸들러나, 미들웨어를 거쳐서, 통신 할 경우 도메인이 localhost가 되어, 401 에러가 발생하게 됩니다!!이를 해결하기 위해, 로컬에서 두개의 서버를 띄워서 테스트하는 방법말고, 보통 실무나, 현업에서는 배포된 쿠키 로그인 방식을 활용할 떄, 어떻게 Next.js에서 환경 구성을 하는지, 로컬호스트가 아닌, 다른 도메인으로 띄울 수 있는 방법이 있는지 궁금합니다.
-
미해결한 입 크기로 잘라먹는 Next.js(15+)
revalidateTag 사용 시 ReviewDetail 리렌더링
revalidateTag를 사용하더라도 결국 Review page가 모두 리렌더링 되는 것으로 보입니다. 이는 자연스러운 동작일까요? 그렇다면,ReviewDetail에서 사용하고 있는 API (책 상세 정보 가져오기)는 굳이 호출될 필요가 없는데 추가 호출이 되는 것 아닐까요? 이런 상황에서 revalidateTag를 사용하는 게 좋은 방법이 맞는지 궁금합니다!
-
해결됨한 입 크기로 잘라먹는 Next.js(15+)
error.tsx를 app 폴더 바로 아래에 둬도...
error.tsx를 app 폴더 바로 아래에 둬도 footer에서 발생하는 오류는 잡히지 않습니다. app layout에서 발생하는 에러는 error.tsx로 잡히지 않는걸까요?
-
해결됨한 입 크기로 잘라먹는 Next.js(15+)
/book/[id]/page.tsx에서 book type은 왜 지정하지 않나요?
book type은 왜 지정하지 않는지 궁금합니다.그리고 왜 book type은 지정하지않아도 typescript에서 체킹(?)을 하지 않는지도 궁금합니다. 항상 강의잘보고있습니다. 감사합니다. 아래의 가이드라인을 꼭 읽고 질문을 올려주시기 바랍니다 질문 하시기 전에 꼭 확인해주세요- 질문 전 구글에 먼저 검색해보세요 (답변을 기다리는 시간을 아낄 수 있습니다)- 코드에 오타가 없는지 면밀히 체크해보세요 (Date와 Data를 많이 헷갈리십니다)- 이전에 올린 질문에 달린 답변들에 꼭 반응해주세요 (질문에 대한 답변만 받으시고 쌩 가시면 속상해요 )질문 하실때 꼭 확인하세요- 제목만 보고도 무슨 문제가 있는지 대충 알 수 있도록 자세한 제목을 정해주세요 (단순 단어 X)- 질문의 배경정보를 제공해주세요 (이 문제가 언제 어떻게 발생했고 어디까지 시도해보셨는지)- 문제를 재현하도록 코드샌드박스나 깃허브 링크로 전달해주세요 (프로젝트 코드에서 문제가 발생할 경우)- 답변이 달렸다면 꼭 확인하고 반응을 남겨주세요- 강의의 몇 분 몇 초 관련 질문인지 알려주세요!- 서로 예의를 지키며 존중하는 문화를 만들어가요. - 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
-
해결됨한 입 크기로 잘라먹는 Next.js(15+)
PageRouter 프로젝트 생성
PS C:\Users\Master\Desktop\onbite-next> npm run devnpm ERR! Missing script: "dev"npm ERR! npm ERR! To see a list of scripts, run:npm ERR! npm runnpm ERR! A complete log of this run can be found in: C:\Users\Master\AppData\Local\npm-cache\_logs\2024-11-18T14_22_23_262Z-debug-0.log이런 오류가 발생했습니다..
-
해결됨한 입 크기로 잘라먹는 Next.js(15+)
9.4) 최적화 후 배포시 빌드시 /book/bookId 의 프리렌더링 에러가 발생하는거 같아요
안녕하세요, 9.4 강의 최적화 후 배포 빌드때 문제가 발생했습니다.- 에러메시지book/[id]/page.tsx 소스코드server는 이미 배포가 되어있고.. vercel 서버 URL도 환경설정 잘 적용된거 확인했고.로컬에서 npm run build까지 잘되었는데혹시 any타입 빌드를 해결하려고 (.)book/[id]/page.tsx에서 이런식으로 프롭스를 넘겨서 발생한 문제일까요..?
-
해결됨한 입 크기로 잘라먹는 Next.js(15+)
스트리밍 SEO 질문드립니다.
스트리밍은 Fetch 등 서버 컴포넌트에서 비동기 실행되는 것들이 완료되기 전에 로딩 화면 같은 것을 보여주는 것이라 이해했습니다. 그렇다면, 스트리밍을 사용하기 않는다면 API를 호출하고 이를 기다린 후, 이에 대한 데이터가 HTML에 포함되어 SEO에 도움을 줄 것 같은데요.스트리밍을 사용한다면 HTML에 로딩 데이터가 보여집니다. 이를 해결할 수 있는 방법이 있나요? 아니면, 이는 SEO를 고려하지 않는 곳에서 사용해야 하는 기법인지 궁금합니다.
-
해결됨한 입 크기로 잘라먹는 Next.js(15+)
실습용 백엔드 서버 세팅
PS C:\Users\Master\Desktop\onebite-books-server-main> npx prisma db pushEnvironment variables loaded from .envPrisma schema loaded from prisma\schema.prismaDatasource "db": PostgreSQL database "postgres", schema "public" at "aws-0-ap-northeast-2.pooler.supabase.com:6543"이렇게 뜨고 성공했다는 문구는 안 뜹니다..
-
미해결Next + React Query로 SNS 서비스 만들기
배포하신 깃헙 auth.ts signOut 질문입니다
https://github.com/ZeroCho/z-com/blob/master/src/auth.ts#L16배포하신 깃헙에서 궁금한점이 생겨서 질문드립니다1. signOut에서 백엔드로 로그아웃 요청만 보내고 authorize()처럼 쿠키값을 set해주지 않았으니 connect.sid는 남아있는게 맞나요? 2. next auth 세션값이 지워지면서 프론트서버와 인증이 끊기는데 프론트서버에서 굳이 백엔드로 요청을 보내는 이유가 뭘까요? 백엔드 서버에 로그 남기기 위해서인가요?
-
미해결Next + React Query로 SNS 서비스 만들기
form으로 put, patch, delete 요청이 안되는걸로 알고있습니다.
form으로 put, patch, delete 요청이 안되는걸로 알고있는데그럼 msw로 목업 요청을 작성할때랑 실제 서버를 작성할때랑 컴포넌트를 두개만들어서 해야하나요?
-
해결됨한 입 크기로 잘라먹는 Next.js(15+)
동적인 데이터를 SSR로 처리할때 초기 로딩 속도에 관하여 질문드립니다!
Next.js로 사전 렌더링을 하여 서버에서 html을 채워서 클라이언트에 응답해줄때 초기로딩 속도가 빨라진다는 개념은 이해가 됩니다. 다만, 제가 확인하고 싶은 부분은 다음과 같습니다. Next.js로 SSR을 구현할때 API 요청과 같이 서버에서 동적인 데이터를 통해 html을 채워서 응답하는 경우에는 요청마다 서버에서 JS를 실행해야 할 것입니다. 이 경우에 CSR보다 초기 로딩 속도가 빠르다고 장담할 수 있나요? (FCP, TTI 모두 어떤 상황에서든 우세할까요?)
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)
쿠키 저장이 되지 않습니다.
auth.ts에서 //비번이 맞으면 토큰 생성 const token = jwt.sign({username}, process.env.JWT_SECRET) console.log(token) //쿠키 저장 res.set("Set-Cookie", cookie.serialize('token', token)); return res.json({user, token});token은 잘 찍히고 요청 헤더에 포함되어 있는데TypeError serialize 부분에서 에러가 뜨고실제 응답 에러가 납니다.... 쿠키 저장이 안되는 것 같습니다.serialize가 undefine 되었다는데 위에 const token으로 제대로 선언되고 출력까지 잘 되는데 이유를 모르겠습니다...
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)
AxiosError {message: 'Request failed with status code 401/500', name: 'AxiosError', code: 'ERR_BAD_RESPONSE', (2)
아래 질문 관련입니다.server.ts origin 부분을 강사님처럼 다음과 같이 작성하면 header 오류가 납니다.const origin = process.env.ORIGIN; app.use(cors({ origin, credentials: true }))근데 아래처럼 const origin을 다음과 같이 환경변수를 거치지 않고 명시하면 헤더 오류 대신 500 오류가 나면서 토큰이 생성되지 않습니다. (로그인 페이지에서 로그인 시)const origin = 'http://localhost:3000'; app.use(cors({ origin, credentials: true })) 서버에서 process.env.ORIGIN, process.env.JWT_SECRET을 찍어봤을땐 잘 나오는데...이 이유로 //비번이 맞으면 토큰 생성 const token = jwt.sign({username}, process.env.JWT_SECRET)이 명령줄이 제대로 실행되지 않는 걸까 싶어 process.env.JWT_SECRET를 'super_secret'으로 바꿔봐도 똑같은 증상입니다. 확실하진 않지만 이 때문에 토큰 생성에 오류가 생겨서 500 에러가 뜨는 것인가 싶은데 어떻게 해결하면 좋을까요?
-
미해결손에 익는 Next.js - 블로그 만들기
완강하고 질문 드립니다
우선 강의 잘 봤습니다.nextjs와 관련된 질문들이 있습니다. SSR,CRS,SSG,PPR,ISR 등은 만약 실무에서 투입한다면개발자들이 렌더링이 어떻게 되어야한다는 도메인 지식이 있는하에 결정하는건가요?그리고 블로그성 개발 관련 질문입니다.이 블로그라는게 어떻게 개발하고 만드냐는 여러가지 방법이 있겠지만 현 강의 처럼 mdx 파일에 직접 포스트를 기재를 하고 빌드해서 배포하고 올린다? 가 있고, CRUD를 구현해 블로그성 홈페이지를 만드는 방법이 있겠는데 보통 개발자분들은 어떤 방법으로 블로그를 만드는지 궁금합니다. (개인적인 의견으로 답변주심 감사하겠습니다(_ _).그리고 만약 mdx파일로 한다고 하면, md파일을 직접 작성해서 올리는것 말고 티스토리와 일반 블로그같은 UI를 생성해서 mdx파일로 올릴수있는지?도 궁금합니다.
-
해결됨한 입 크기로 잘라먹는 Next.js(15+)
데이터 페칭이 되면 React Query를 대체할 수 있을까요?
강의를 들어보니 React Query와 꽤 비슷한 부분이 많다고 생각되서 혹시 대체할 수 있을까 생각이 들었는데요. 정환님은 어떤 생각을 가지고 계신지 궁금하여 질문 드립니다. 만약 App Router로 새로운 프로젝트를 구축해야 한다고 하면 React Query를 사용하실건가요?
-
미해결[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
db관련 질문있습니다.
postgres 주소는 오프라인 강의 시에만 제공하고 온라인은 제공을 하지 않는다고 이해했는데요.해당 부분으로 대체 가능한 방법과 postgres 없이 graphql만 실행하여 강의를 따라가도 지장이 없는지 궁금합니다.이후 강의에는 데이터 처리하는 부분이 포함되어있는 것 같은데요. 해당부분 확인 바랍니다!
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)
AxiosError {message: 'Request failed with status code 401/500', name: 'AxiosError', code: 'ERR_BAD_RESPONSE',
로그인 페이지에서 로그인을 하면 500, 커뮤니티 생성 페이지에서 생성을 하면 401 AxiosError가 뜹니다. <login.tsx>import axios from 'axios'; import InputGroup from '../components/InputGroup' import Link from 'next/link' import { useRouter } from 'next/router'; import React,{ FormEvent, useState } from 'react' import { useAuthDispatch } from '../context/auth'; axios.defaults.withCredentials = true; const Login = () => { let router = useRouter(); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [errors, setErrors] = useState<any>({}); const dispatch = useAuthDispatch(); const handleSubmit = async (event: FormEvent) => { event.preventDefault(); try{ const res = await axios.post("/auth/login", {password, username}, {headers: {'Access-Control-Allow-Origin': 'http://localhost:3000'}}) dispatch("LOGIN", res.data?.user); } catch(error: any){ //console.log(error); setErrors(error.response?.data || {}) } } return ( <div className='bg-white'> <div className='flex flex-col items-center justify-center h-screen p-6'> <div className='w-10/12 mx-auto md:w-96'> <h1 className='mb-2 text-lg font-medium'>로그인</h1> <form onSubmit={handleSubmit}> <InputGroup placeholder='Username' value={username} setValue={setUsername} error={errors.username} /> <InputGroup placeholder='Password' value={password} setValue={setPassword} error={errors.password} /> <button className='w-full py-2 mb-1 text-xs font-bold text-white uppercase bg-gray-400 border border-gray-400 rounded'> 로그인 </button> </form> <small> 아직 아이디가 없으신가요? <Link href="/register" legacyBehavior> <a className='ml-1 text-blue-500 uppercase'>회원가입</a> </Link> </small> </div> </div> </div> ) } export default Login<create.tsx>import axios from "axios"; import { GetServerSideProps } from "next"; import InputGroup from "../../components/InputGroup" import {useState, FormEvent} from "react"; import {useRouter} from "next/router" axios.defaults.withCredentials = true; const SubCreate = () => { const [name, setName] = useState(""); const [title, setTitle] = useState(""); const [description, setDescription] = useState(""); const [errors, setErrors] = useState<any>({}); let router = useRouter(); const handleSubmit = async (event: FormEvent) => { event.preventDefault(); try { const res = await axios.post("/subs", {name, title, description}, {headers: {'Access-Control-Allow-Origin': 'http://localhost:3000'}}) router.push(`/r/${res.data.name}`); } catch (error: any) { // console.log(error); setErrors(error.response?.data || {}); } } return ( <div className="flex flex-col justify-center pt-16"> <div className="w-10/12 mx-auto md:w-96"> <h1 className="mb-2 text-lg font-medium"> 그룹 만들기 </h1> <hr /> <form onSubmit={handleSubmit}> <div className="my-6"> <p className="font-medium">Name</p> <p className="mb-2 text-xs text-gray-400"> 그룹 이름은 변경할 수 없습니다. </p> <InputGroup placeholder="이름" value={name} setValue={setName} error={errors.name} /> </div> <div className="my-6"> <p className="font-medium">Title</p> <p className="mb-2 text-xs text-gray-400"> 주제를 입력해 주세요. </p> <InputGroup placeholder="주제" value={title} setValue={setTitle} error={errors.title} /> </div> <div className="my-6"> <p className="font-medium">Description</p> <p className="mb-2 text-xs text-gray-400"> 그룹에 대한 설명을 입력해주세요. </p> <InputGroup placeholder="설명" value={description} setValue={setDescription} error={errors.description} /> </div> <div className="flex jstify-end"> <button className="px-4 py-1 text-sm font-semibold rounded text-white bg-gray-400 border" > 그룹 만들기 </button> </div> </form> </div> </div> ) } export default SubCreate<subs.ts>import {Router, Request, Response} from "express"; import jwt from "jsonwebtoken" import { User } from "../entities/User"; import userMiddleware from "../middlewares/user" import authMiddleware from "../middlewares/auth" import { AppDataSource } from "../data-source"; import Sub from "../entities/Sub"; import { isEmpty } from "class-validator"; const createSub = async (req: Request, res: Response, next) => { const {name, title, description} = req.body; try { let errors: any = {}; if (isEmpty(name)) errors.name = "이름은 비워둘 수 없습니다."; if (isEmpty(title)) errors.title = "제목은 비워둘 수 없습니다."; const sub = await AppDataSource.getRepository(Sub) .createQueryBuilder("sub") .where("lower(sub.name) = :name", { name: name.toLowerCase() }) .getOne(); if (sub) errors.name = "서브가 이미 존재합니다."; if (Object.keys(errors).length > 0) { throw errors; } } catch (error) { console.log(error); return res.status(500).json({ error: "문제가 발생했습니다." }); } try { const user: User = res.locals.user; const sub = new Sub(); sub.name = name; sub.description = description; sub.title = title; sub.user = user; await sub.save(); return res.json(sub); } catch (error) { console.log(error); return res.status(500).json({ error: "문제가 발생했습니다." }); } }; const router = Router(); router.post("/", userMiddleware,authMiddleware, createSub); export default router; <server.ts>import express, { response } from "express"; import morgan from "morgan"; import { AppDataSource } from "./data-source"; import authRoutes from './routes/auth' import subRoutes from './routes/subs' import cors from 'cors'; import dotenv from 'dotenv'; import cookieParser from "cookie-parser"; const app = express(); const origin = process.env.ORIGIN; const corsOption = { origin: "http://localhost:3000", credentials: true } app.use(cors(corsOption)) app.use(express.json()); app.use(morgan('dev')); app.use(cookieParser()); dotenv.config(); app.get("/", (_, res) => {res.send("running")}); app.use("/api/auth", authRoutes) app.use("/api/subs", subRoutes) console.log(process.env.ORIGIN) let port = 4000; app.listen(port, async () => { console.log('server running at http://localhost:${port}'); AppDataSource.initialize().then(async () =>{ console.log("database initialized") }).catch(error => console.log(error)) }) 아무리 구글링해봐도 기본 지식이 부족해서 도저히 해결이 안되네요ㅠㅠ 조금 급하게 만들어야 하는 상황이라.... 도와주세요...!
-
해결됨한 입 크기로 잘라먹는 Next.js(15+)
Image의 src에 경로를 작성하는 것과 import로 이미지를 가져와서 넣는 것의 차이가 궁금합니다!
<Image src="/logo.png" alt="로고" width={100} height={100} /> import Logo from "@/public/logo.png"; <Image src={Logo} alt="로고" width={100} height={100} />이 두가지 접근 방식의 차이가 있을까요?
-
해결됨한 입 크기로 잘라먹는 Next.js(15+)
포괄적 에러 핸들링 error.tsx이 정상 작동 하지 않습니다 (05:30)
안녕하세요서버는 종료한 상태에서 강의대로 (with-searchbar)/error.tsx 파일을 만들고 새로고침을 하면 error.tsx에서 작성한 페이지가 나오지 않습니다.error.tsx 인덱스 페이지 아래 사진처럼 error.tsx페이지가 아닌핸들링되지 않은 런타임 에러가 발생해버립니다..혹시 searchParams를 Promise객체로 타입정의 한것처럼 뭔가 사용방법이 바뀐걸까요..?