- Published on
2025.04.11
[리액트 딥다이브] - 04. 서버 사이드 렌더링(2)
4.3. Next.js 톺아보기
4.3.1. Next.js란?
풀스택 웹 애플리케이션을 구축하기 위한 리액트 기반 프레임워크
현재는 리액트 공식 문서에서도 설치 단계에서 소개할 정도로 대표적인 프레임워크
4.3.2. Next.js 시작하기
pages/_app.tsx
_app.tsx
와 내부의 default export로 내보낸 함수는 애플리케이션 전체 페이지의 시작점. 웹 애플리케이션의 공통 설정들을 실행 가능.
- 에러 바운더리로 전역 에러 처리
reset.css
같은 전역 CSS 선언- 모든 페이지에 공통으로 사용 또는 제공하는 데이터 제공 등
pages/_document.tsx
HTML 설정과 관련된 코드를 추가하는 곳이며 반드시 서버에서만 렌더링된다.
CSS-in-JS의 스타일을 서버에서 모아 HTML로 제공하는 작업은 _document.tsx
에서만 가능.
_app.tsx
와의 차이점
<html>
이나<body>
에 DOM 속성을 추가하고 싶을 때 사용_document
는 무조건 서버에서 실행된다. 그러므로 이벤트 핸들러를 추가하는 것은 불가능getServerSideProps
,getStaticProps
등 서버에서 사용 가능한 데이터 페칭 함수는 사용 불가
pages/_error.tsx
클라이언트에서 발생하는 에러 또는 서버에서 발생하는 500 에러를 처리
개발 모드에서는 Next.js 개발자 에러 팝업이 나타나므로 방문할 수 없고, 프로덕션에서 빌드해 확인할 수 있음
pages/_404.tsx
404 페이지를 정의하는 파일, 만들지 않으면 Next.js의 기본 404 페이지가 조회
pages/_500.tsx
서버에서 발생하는 에러를 핸들링하는 페이지로, _error.tsx
와 500.tsx
가 모두 있으면 500.tsx
가 우선적으로 실행됨.
pages/_index.tsx
위의 예약어로 관리되는 페이지와 달리 명칭을 지정해 만들 수 있는 각 페이지의 루트 컴포넌트로 default export로 내보낸 함수를 담은 페이지
Next.js의 라우팅 구조는 /pages 디렉토리를 기초로 구성되며, 각 페이지의 default export가 루트 컴포넌트가 됨
- /pages/index.tsx: 웹사이트의 루트
- /pages/hello.tsx: /pages가 생략되고, 파일명이 주소가 됨, 이 경우에는 localhost:3000/hello가 된다
- /pages/hello/world.tsx: localhost:3000/hello/world, 디렉토리의 깊이만큼 주소 설정 가능
- /pages/hello/[greeting].tsx: 어떠한 문자도 올 수 있다는 의미, /pages/hello/world.tsx와 같이 이미 정의된 주소가 있다면 미리 정의된 주소가 우선
- /pages/hi/[...props].tsx: /hi를 제외한 /hi 하위의 모든 주소가 여기로 온다. [...props] 값은 props라는 변수에 배열로 오게 됨
서버 라우팅과 클라이언트 라우팅의 차이
<a>
: 서버에서 렌더링 수행, 클라이언트에서 hydrate<Link>
: 서버 사이드 렌더링이 아닌, 클라이언트 라우팅/렌더링 방식으로 작동
서버 사이드 렌더링의 장점과 SPA의 장점을 모두 살리기 위해 이러한 방식으로 작동
Next.js의 장점을 살리기 위해 다음과 같이 사용
<a>
대신<Link>
사용window.location.push
대신router.push
사용
페이지에서 getServerSideProps를 제거하면 어떻게 될까?
getServerSideProps
가 없으면 서버에서 실행하지 않아도 되는 페이지로 처리
typeof window의 처리를 모두 object로 바꾸고, 빌드 시점에 트리쉐이킹 처리
pages/api/_hello.ts
/pages 하단에 api라고 작성된 디렉토리는 서버의 API를 정의하는 폴더
/pages/api/hello.ts는 /api/hello로 호출할 수 있다.
- 서버에서 내려주는 데이터를 조합해 BFF형태로 활용
- 풀스택 애플리케이션 구축 시
- CORS 우회용
4.3.3. Data Fetching
서버 사이드 렌더링 지원을 위한 데이터 불러오기 전략
pages/의 폴더에 있는 라우팅이 되는 파일에서만 사용 가능
예약어로 지정되어 반드시 정해진 함수명으로 export를 사용해 함수를 파일 외부로 내보내야 함
getStaticPaths와 getStaticProps
두 함수는 특정 페이지를 CMS, 블로그, 게시판과 같은 사용자와 관계없이 정적인 페이지를 보여주고자 할 때 사용, 두 함수는 반드시 함께 있어야 사용 가능
getStaticPaths
는 페이지가 접근 가능한 주소를 정의하는 함수, paths를 배열로 반환하는데, params를 키로 하는 함수에 값을 넘겨 해당 페이지에서 접근 가능한 페이지를 정의할 수 있다. /pages/post/[id] 기준 paths: [{ params: { id: '1' }}, { parms: { id: '2' }}]
라면 /post/1과 /post/2만 접근 가능함을 의미. 다른 경로는 404를 리턴.
fallback 옵션을 통해 미리 빌드하지 않은 페이지에 접근한 경우, 빌드 전까지 fallback 컴포넌트를 보여주고, 빌드 완료 후 해당 페이지를 보여주도록 처리 가능
getStaticProps
는 앞에서 정의한 페이지를 기준으로 요청이 왔을 때 제공할 props를 반환하는 함수, 앞서 1과 2로 제한함으로 fetchPost(1), fetchPost(2)를 기준으로 각각 함수의 응답 결과를 변수로 가져와 props의 { post }
로 리턴.
getServerSideProps
서버에서 실행되는 함수로, 해당 함수가 있다면 무조건 페이지 진입 전에 함수를 실행. 응답값에 따라 페이지의 루트 컴포넌트에 props를 반환하거나 다른 페이지로 리다이렉트시킬 수 있음.getServerSideProps
는 반드시 JSON.stringify
로 직렬화할 수 있는 값만 제공해야 함. 또, 무조건 서버에서 실행되므로 갖는 제약이 있음
window.document
와 같은 브라우저에서만 접근할 수 있는 객체에 접근 불가- API 호출 시 /api/some/path처럼 프로토콜과 도메인 없이 fetch 요청 불가, 서버는 자신의 호스트를 유추할 수 없기 때문. 완전한 주소를 제공해야 함
- 에러가 발생하면 500.tsx와 같이 미리 정의해 둔 에러 페이지로 리다이렉트
사용자가 매 페이지를 호출할 때마다 실행되고, 실행 완료 전까지는 어떠한 HTML도 보여줄 수 없으므로 최대한 간결하게 작성해야 함.
getInitialProps
getStaticProps와 getServerSideProps가 나오기 전 사용하던 유일한 데이터 페칭 함수.
라우팅에 따라 서버와 클라이언트 모두에서 실행 가능한 메서드
다른 페칭 함수에 비해 사용하기 까다롭고 주의점이 많아 getStaticProps와 getServerSideProps를 사용
4.3.4. 스타일 적용하기
전역 스타일
CSS Reset이라 불리는 브라우저 기본 스타일 초기화 등은 _app.tsx
에 필요한 스타일을 import해 적용
컴포넌트 레벨 CSS
[name].module.css와 같은 명명 규칙을 준수하여 가능
SCSS와 SASS
css와 동일한 방식으로 사용 가능. scss에서 제공하는 varible을 컴포넌트에서 사용하고 싶다면 export 문법 사용
CSS-in-JS
리액트 트리 내부에서 사용되는 styled-component의 스타일을 모은 후, 클래스명을 부여해 스타일이 충돌하지 않게 클래스명과 스타일을 정리해 _document.tsx
가 서버 렌더링 시 React.Context 형태로 제공한다.
4.3.6. next.config.js 살펴보기
자주 사용되는 설정
- basePath: URL을 위한 접두사로, 모든 주소에 basePath가 붙은 채로 렌더링 됨
- swcMinify: swc로 코드를 압축할지 정함, 기본값은 true
- poweredByHeader: 응답 헤더에 X-Power-by: Next.js 정보를 제공할 지 여부로, 취약점으로 분류되므로 false 추천
- redirects: 특정 주소를 다른 주소로 보내고 싶을 때 사용
- reactStrictMode: 엄격 모드 설졍 여부, 기본값 false
- assetPrefix: 빌드 결과물을 동일한 호스트가 아닌 다른 CDN 등에 업로드하고자 할 때 옵션에 해당 CDN 주소를 명시