NextJS
Next JS란?
React의 SSR(server side rendering)을 쉽게 구현할 수 있게 도와 주는 간단한 프레임워크이다. (리액트는 라이브러리)
React로 개발할 때 SPA(single Page Application)을 이용하며 CSR(Client Side Rendering)을 하기 때문에 좋은 점도 있지만 단점도 있는데 그 부분이 바로 검색엔진 최적화(SEO) 부분이다.
Client Side Rendering을 하면 첫페이지에서 빈 html을 가져와서 JS파일을 해석하여 화면을 구성 하기 때문에 포털 검색에 거의 노출 될 일이 없다.
하지만 Next.js에서는 Pre-Rendering을 통해서 페이지를 미리 렌더링 하며 완성된 HTML을 가져오기 때문에 사용자와 검색 엔진 크롤러에게 바로 렌더링 된 페이지를 전달할 수 있게 된다.
리액트에서도 SSR을 지원하기면 구현하기에 굉장히 복잡하기 때문에 Next.js를 통해서 이 문제를 해결해주게 된다.

Server Side Rendering
- 클라이언트 대신 서버에서 페이지를 준비하는 원리이다.
- 원래 React에서는 클라이언트 사이드 렌더링하기 때문에 서버에 영향을 미치지 않고, 서버에서 클라이언트로 응답해서 보낸 html도 거의 비어있다.
=> 이 방식은 서버에서 데t이터를 가져올 때 지연 시간 발생으로 UX 측면에서 좋지 않을 수 있다.
=> 검색 엔진에 검색 시 웹크롤링이 동작할 때 내용을 제대로 가져와 읽을 수 없기에 검색엔진 최적화에 문제가 된다.
- Next.js에서는 서버 사이드 렌더링을 이용하므로 사용자와 검색 엔진 크롤러에게 바로 렌더링 된 페이지를 전달 할 수 있어서 검색엔진 최적화에 좋은 영향을 준다.
설치 방법
폴더를 만든 후, 터미널에 다음 명령을 입력한다.
npm create-next-app@latest --typescript ./
강의대로 따라가면 강의와 다른 폴더 구조가 생성된다. 이는 다음과 같이 터미널에 입력하면 강의와 같은 폴더 구조로 받을 수 있다.
npx create-next-app@12.1.0 --typescript ./
NextJS 기본 파일 구조

pages
- 이 폴더 안에 페이지들을 생성한다.
- index.tsx가 처음 "/" 페이지로 된다.
- _app.tsx 는 공통되는 레이아웃을 작성한다. 모든 페이지에 공통으로 들어가는 걸 넣어주려면 여기에 넣으면 된다. (url을 통해 특정 페이지에 진입하기 전 통과하는 인터 셉터 페이지이다.)
- 만약 about이라는 페이지를 만들려면 pages 폴더 안에 about.tsx를 생성해주면 된다.
public
- 이미지 같은 정적(static) 에셋들을 보관한다.
styles
- 말 그래도 스타일링을 처리해주는 폴더이다.
- 모듈(module) css는 컴포넌트를 종속적으로 스타일링 하기 위한 것이며, 확장자 앞에 module을 붙여줘야 한다.
next.config.js
- Nextjs는 웹팩을 기본 번들러로 사용한다.
- 그래서 웹팩에 관한 설정들을 이 파일에서 해줄 수 있다.
Pre-rendering
NextJS는
모든 페이지를 pre-render 한다. 이 pre-render한다는 의미는 모든 페이지를 위한 HTML을 Client사이드에서 자바스크립트로 처리하기 전, "사전에" 생성한다는 것이다.
이렇게 하기 때문에 SEO 검색엔진 최적화가 좋아진다.
Pre Render 테스트
자바스크립트 Disable
https://developer.chrome.com/docs/devtools/javascript/disable/

링크에 들어가서 개발자 도구를 연 후, command+shift+p를 눌러주고 자바스크립트를 검색해준다. 그리고 자바스크립트 사용 중지를 선택해준다.

그리고 소스에 노란 표시가 뜨면, 자바스크립트가 disable된 것을 알 수 있다.
보통 React 사이트 들어가기
https://create-react-app.examples.vercel.com

여기서도 똑같이 진행해주고 refresh를 해주면 위와 같이 창이 뜬다.
그리고 다시 풀어주고 refresh해주면 원래대로 돌아가는 것을 확인할 수 있다.

NextJS 사이트 들어가기
https://next-learn-starter.vercel.app/
NextJS에서는 Disable을 해줘도, 정상작동하는 것을 볼 수 있다.

Pre-rendering을 하기 때문에 disable시켜도 볼 수 있는 것이다.
보통의 React 앱에서는 Pre-rendering을 하지 않는다.

Data Fetching
Nextjs에서 데이터를 가져오는 방법은
여러가지가 있다. 그래서 애플리케이션의 사용 용도에 따라서 다른 방법을 사용해주면 된다.
보통 React에서는 데이터를 가져올 때 useEffect안에서 가져온다. 하지만 Next.js에서는 다른 방법을 사용해서 가져온다. 계속해서 살펴보자.

getStaticProps
- getStaticProps 함수를 async로 export하면, getStaticProps에서 리턴되는 props를 가지고 페이지를 pre-render 한다. build time에 페이지를 렌더링한다.


getStaticProps를 사용해야 할 때
- 페이지를 렌더링하는 데 필요한 데이터는 사용자의 요청보다 먼저 build 시간에 필요한 데이터를 가져올 때
- 데이터는 Headless CMS에서 데이터를 가져올 때.
- 데이터를 공개적으로 캐시할 수 있을 때(사용자별 아님).
- 페이지는 미리 렌더링되어야 하고(SEO의 경우) 매우 빨라할 때.(getStaticProps는 성능을 위해 CDN에서 캐시할 수 있는 HTML 및 JSON 파일을 생성한다.)
getStaticPaths

- 동적 라우팅이 필요할 때 getStaticPaths로 경로 리스트를 정의하고, HTML에 build 시간에 렌더링된다.
- Nextjs는 pre-render에서 정적으로 getStaticPaths에서 호출하는 경로들을 가져온다.
paths
- 어떠한 경로가 pre-render 될지를 결정한다.
- 만약 pages/posts/[id].js 이라는 이름의 동적 라우팅을 사용하는 페이지가 있다면 아
래와 같이 된다.

- 빌드하는 동안 /posts/1과 /posts/2를 생성하게 된다.
params
- 페이지 이름이 pages/posts/[postId]/[commentId] 라면 , params은 postId와 commentId이다.
- 만약 페이지 이름이 pages/[...slug] 와 같이 모든 경로를 사용한다면, params는 slug 가 담긴 배열이어야한다. ['postId', 'commentId']
fallback
- false 라면 getStaticPaths로 리턴되지 않는 것은 모두 404 페이지가 뜬다.
- true 라면 getStaticPaths로 리턴되지 않는 것은 404로 뜨지 않고, fallback 페이지가 뜨게 된다.



getServerSideProps
- getServerSideProps 함수를 async로 export 하면, Next는 각 요청마다 리턴되는 데이터를 getServerSideProps로 pre-render한다.

getServerSideProps를 사용해야 할 때
- 요청할 때 데이터를 가져와야하는 페이지를 미리 렌더해야 할 때 사용한다. 서버가 모든 요청에 대한 결과를 계산하고, 추가 구성없이 CDN에 의해 결과를 캐시할 수 없기 때문에 첫번째 바이트까지의 시간은 getStaticProps보다 느리다.
-> 데이터가 많이 바뀔 때는 계속 데이터가 바뀐 것을 새로 가져와야 한다. 즉, request를 보낼 때마다 새롭게 데이터를 가져올 수 있게 하기 위해 getServerSideProps를 사용해주면 된다.