Next.js 서버 사이드 렌더링(SSR) 완벽 가이드

작성일 :

Next.js 서버 사이드 렌더링(SSR) 완벽 가이드

Next.js는 React 기반 애플리케이션을 개발하는 데 있어 강력한 도구입니다. 특히, 서버 사이드 렌더링(SSR) 기능을 제공함으로써 SEO 최적화와 초기 로딩 속도를 크게 개선할 수 있습니다. 이 가이드에서는 Next.js에서 서버 사이드 렌더링을 설정하고 사용하는 방법을 단계별로 설명합니다.

서버 사이드 렌더링 vs 클라이언트 사이드 렌더링

서버 사이드 렌더링과 클라이언트 사이드 렌더링의 주요 차이점을 이해하는 것이 중요합니다.

  • 서버 사이드 렌더링 (SSR): 페이지 요청 시 서버에서 HTML을 렌더링하여 클라이언트에 전달합니다. 초기 로드 속도가 빠르고, 검색 엔진에 의해 쉽게 크롤링됩니다.

  • 클라이언트 사이드 렌더링 (CSR): 클라이언트가 페이지를 요청할 때 빈 HTML 파일을 받고, 이후 JavaScript가 실행되어 전체 UI를 렌더링합니다. 이는 동적이고 상호작용적인 애플리케이션에 유용하지만, 초기 로드 시간과 SEO 측면에서는 불리할 수 있습니다.

프로젝트 설정

Next.js 프로젝트를 설정하려면 다음 명령어를 사용합니다:

bash
npx create-next-app my-nextjs-app
cd my-nextjs-app
npm run dev

위 명령어로 기본 Next.js 애플리케이션이 생성됩니다. 이제 우리는 서버 사이드 렌더링을 설정해 보겠습니다.

페이지 생성 및 초기 데이터 패칭

Next.js에서 서버 사이드 렌더링을 구현하기 위해 getServerSideProps 함수를 사용합니다. 이 함수는 각각의 페이지 컴포넌트 내에서 사용되며, 서버에서 데이터를 패칭한 후 그 데이터를 페이지에 전달합니다.

jsx
// pages/index.js

export async function getServerSideProps() {
  const res = await fetch('https://api.example.com/data');
  const data = await res.json();

  return {
    props: {
      data,
    },
  };
}

const Home = ({ data }) => {
  return (
    <div>
      <h1>서버 사이드 렌더링 예제</h1>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
};

export default Home;

위 예제에서 getServerSideProps 함수는 API로부터 데이터를 패칭하고, 이를 Home 컴포넌트에 props로 전달합니다. 페이지가 요청될 때마다 이 함수가 실행되므로 항상 최신 데이터를 받을 수 있습니다.

동적 라우팅과 SSR

Next.js에서는 동적 라우팅과 SSR을 쉽게 결합할 수 있습니다. 예를 들어, 블로그 포스트와 같은 동적 경로를 갖는 페이지를 만들어 보겠습니다.

jsx
// pages/posts/[id].js

export async function getServerSideProps({ params }) {
  const res = await fetch(`https://api.example.com/posts/${params.id}`);
  const post = await res.json();

  return {
    props: {
      post,
    },
  };
}

const Post = ({ post }) => {
  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  );
};

export default Post;

위 예제에서는 params 객체를 통해 동적 라우팅의 경로 정보를 받아옵니다. 이를 이용해 데이터 패칭을 수행하고, 받은 데이터를 페이지 컴포넌트에 전달합니다.

API 라우트와 SSR

Next.js는 내장 API 라우트 기능을 제공하여 서버 사이드 코드를 손쉽게 작성할 수 있게 합니다. 이를 통해 데이터베이스와의 통합도 용이합니다. API 라우트를 정의하는 방법은 다음과 같습니다:

jsx
// pages/api/hello.js

export default function handler(req, res) {
  res.status(200).json({ message: 'Hello from Next.js API' });
}

이제 이 API 라우트를 사용할 수 있습니다:

jsx
// pages/index.js

export async function getServerSideProps() {
  const res = await fetch('http://localhost:3000/api/hello');
  const data = await res.json();

  return {
    props: {
      message: data.message,
    },
  };
}

const Home = ({ message }) => {
  return (
    <div>
      <h1>{message}</h1>
    </div>
  );
};

export default Home;

최적화와 고려사항

서버 사이드 렌더링을 사용할 때 주의할 점 몇 가지:

  1. 서버 부하: 모든 요청마다 서버에서 렌더링을 수행하므로 서버 부하가 증가할 수 있습니다. 캐싱 전략을 사용하여 부하를 줄이는 것이 좋습니다.
  2. 속도: 초기 로드 속도는 빠르지만, 데이터 패칭이 느려지면 전체 페이지 렌더링 시간도 느려질 수 있습니다. 고성능 API와 효율적인 데이터베이스 쿼리가 필요합니다.
  3. 보안: 서버에서 데이터를 처리하므로 민감한 데이터를 클라이언트에 보내기 전에 항상 보안 조치가 필요합니다.
  4. SEO: 서버 사이드 렌더링은 SEO에 유리하지만, 올바른 meta 태그와 robots.txt 파일 설정이 필수적입니다.

결론

Next.js의 서버 사이드 렌더링을 활용하면 높은 성능과 SEO 최적화된 웹 애플리케이션을 쉽게 구축할 수 있습니다. getServerSideProps와 동적 라우팅, API 라우트를 결합하여 복잡한 요구사항을 충족하는 애플리케이션을 개발해 보세요.