Next.js - next.config.js

tunggary·2022년 3월 1일
1

Next.js

목록 보기
6/7
post-thumbnail

next를 좀 더 커스텀하게 사용하기 위해 next.config.js 파일에서 기본 설정을 할 수 있다. next.config.js 는 JSON 파일이 아닌 일반 Node 모듈이고 next 서버 빌드 단계에서 사용되며 브라우저 빌드에는 포함되지 않는다.

1. 환경변수

next.config.js 파일에서 환경변수를 설정하는 방법은 다음과 같다.

module.exports = {
  env: {
    PRIVATE_KEY_CONFIG: "0123456789abcdefghijk",
  },
};

사용할 때는 process.env.{key_name} 와 같이 접근해서 사용하면 된다.

export default function Home() {
  //환경 변수
  const config = process.env.PRIVATE_KEY_CONFIG;

  return (
    <div>
      <div>env variable in config file : {config}</div>
    </div>
  );
}

.env
.env 파일을 이용해서 환경변수를 설정할 수도 있는데, 이 때 주의해야 할 점
1. next 서버에서만 사용하는 경우 : 일반적인 환경변수 처럼 작성

PRIVATE_KEY=0123456789abcdefghijk
  1. next 서버, 브라우저에서도 사용하는 경우 : 접두사에 NEXT_ PUBLIC_ 을 붙이면 브라우저에서 실행되는 코드에서도 환경변수를 사용할 수 있다.
NEXT_PUBLIC_PRIVATE_KEY=0123456789abcdefghijk

2. Base Path

next에서 base path를 설정하려면 next.config.js 파일에서 다음과 같이 basePath 속성을 설정하면 된다.

module.exports = {
  basePath: '/docs',
}

이렇게 설정하게 되면 다음과 같은 <Link> 태그에서 이동하게 되면 /about 이 아닌 /docs/about 으로 이동하게 된다.

export default function HomePage() {
  return (
    <>
      <Link href="/about">
        <a>About Page</a>
      </Link>
    </>
  )
}

output html

<a href="/docs/about">About Page</a>

<Image> 태그나 <svg> 태그의 경로에는 적용이 안되므로 전체 경로를 적어주어야 한다.

import Image from 'next/image'

function Home() {
  return (
    <Image
      src="/docs/me.png"
      alt="Picture of the author"
      width={500}
      height={500}
    />
  )
}

export default Home

3. Redirects

Redirection 하기 위해서는 next.config.js 파일에서 redirects 키를 사용하면 된다.

module.exports = {
  async redirects() {
    return [
      {
        source: '/about',
        destination: '/',
        permanent: true,
      },
    ]
  },
}

redirects 함수는 비동기 함수이며, source, destination, permanent 등을 속성으로 가지는 객체 배열을 return 한다.

Properties

  1. source : imcomming request
  2. destination : redirecting 할 경로
  3. permanent : true인 경우 http 코드가 308(permanent)이 되고, false인 경우 http 코드가 307(temporary)이 된다.
  4. basePath : true인 경우 redirection 경로의 basePath가 적용되고, false인 경우 적용이 되지 않는다.
  5. has : object 타입이며 header, cookie, query 매칭을 할 때 사용된다.

http 코드 307, 308 알아보기
http://www.techholic.co.kr/news/articleView.html?idxno=12935#rs

Path matching

redirection이 일어나는 경로를 매칭하는 방법은 다음과 같다.

module.exports = {

  async redirects() {
    return [
      {
        source: '/team',
        destination: '/about',
        permanent: false,
      },
      // Path Matching - will match `/old-blog/a`, but not `/old-blog/a/b`
      {
        source: '/old-blog/:slug',
        destination: '/news/:slug',
        permanent: false,
      },
      // Wildcard Path Matching - will match `/blog/a` and `/blog/a/b`
      {
        source: '/blog/:slug*',
        destination: '/news/:slug*',
        permanent: false,
      },
      // Regex Path Matching - The regex below will match `/post/123` but not `/post/abc`
      {
        source: '/post/:slug(\\d{1,})',
        destination: '/news/:slug',
        permanent: false,
      },
    ]
  },
}

주의할점
permanent: true 로 하게 되면 캐시에 남아 next.config.js 파일을 수정하여도 redirect가 될 수 있다. 이 때는 강력 새로고침을 통해 캐시를 지워줘야 한다.

has 속성을 이용하면 path 뿐만 아니라 다양한 상황에 redirection 을 할 수 있다.
has 는 3가지 key 값을 가지는 object 타입이다.
1. type : String - header, cookie, host, query 중 하나의 값을 가진다.
2. key : String - 선택된 type의 key 값과 매칭이 된다.
3. value: String or undefined - 선택된 type의 key 값의 value 와 매칭이 되며, 문자열 뿐만 아니라 정규식으로 사용될 수 있다.

module.exports = {
  async redirects() {
    return [
      // 만약 source 경로로 들어온 요청의 header에 
      // 'x-redirect-me' key 값이 있으면 redirect 된다.
      {
        source: '/:path((?!another-page$).*)',
        has: [
          {
            type: 'header',
            key: 'x-redirect-me',
          },
        ],
        permanent: false,
        destination: '/another-page',
      },
      // 만약 source 경로로 들어온 요청의 
      // query에 key('page')와 value('home')가 일치하고, 
      // cookie에 key('authorized')와 value('true')가 일치하면 redircet 된다.
      {
        source: '/specific/:path*',
        has: [
          {
            type: 'query',
            key: 'page',
            value: 'home',
          },
          {
            type: 'cookie',
            key: 'authorized',
            value: 'true',
          },
        ],
        permanent: false,
        destination: '/another/:path*',
      },
      // if the header `x-authorized` is present and
      // contains a matching value, this redirect will be applied
      {
        source: '/',
        has: [
          {
            type: 'header',
            key: 'x-authorized',
            value: '(?<authorized>yes|true)',
          },
        ],
        permanent: false,
        destination: '/home?authorized=:authorized',
      },
      // if the host is `example.com`,
      // this redirect will be applied
      {
        source: '/:path((?!another-page$).*)',
        has: [
          {
            type: 'host',
            value: 'example.com',
          },
        ],
        permanent: false,
        destination: '/another-page',
      },
    ]
  },
}

4. Rewrites

redirect의 경우 source경로로 request가 오면 다른 경로로 redirect를 시켜주어 잠시동안 url에 source 경로가 보였다가 다른 경로로 바뀐다. 하지만 rewrites의 경우에는 source경로를 destination경로로 매핑이 되어 url의 변화 없이 바로 destination 경로로 바뀐다.

  module.exports = {
  async rewrites() {
    return [
      {
        source: '/about',
        destination: '/',
      },
    ]
  },
}

위와 같은 경우 클라이언트에서 <Link href="/about"> 태그를 눌렀을때
/about 페이지가 아닌 / 페이지로 이동하게 된다.

이는 api_key를 노출시키지 않고 api를 호출할 때의 유용하게 쓰인다.

import { useEffect, useState } from "react";

const API_KEY = "0123456789abcdefgh";

export default function Home() {
  const [movies, setMovies] = useState();
  useEffect(() => {
    (async () => {
      const { results } = await (
        await fetch(
          `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`
        )
      ).json();
      setMovies(results);
    })();
  }, []);
  return (
  	<div>api 호출</div>
  );
}

이와 같이 api_key를 이용하여 api를 호출하면 클라이언트 network 탭에 api_key가 그대로 노출이 되게 된다.
이를 방지하기 위해 rewirtes를 이용하여 경로에서 api_key가 노출되지 않도록 한다.

next.config.js

const API_KEY = process.env.API_KEY;

module.exports = {
  async rewrites() {
    return [
      {
        source: "/api/movies",
        destination: `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`,
      },
    ];
  },
};

api 호출하는 페이지

import { useEffect, useState } from "react";

export default function Home() {
  const [movies, setMovies] = useState();
  useEffect(() => {
    (async () => {
      const { results } = await (await fetch(`/api/movies`)).json();
      setMovies(results);
    })();
  }, []);
  return (
    <div>api 호출</div>
  );
}
  

이렇게 rewrites를 하게되면 기존의 api_key가 노출되는 경로로 api를 호출하지 않아도 데이터를 정상적으로 받아올 수 있다.

이외에도 next.config.js 에서 설정할 수 있는 것들은 여기에서 확인하면 된다.

References

  1. https://nextjs.org/docs/api-reference/next.config.js/introduction

0개의 댓글