[NextJS] Redirects & Rewrites

๊ฐ•์€๋น„ยท2022๋…„ 6์›” 13์ผ
1

NextJS

๋ชฉ๋ก ๋ณด๊ธฐ
5/10
post-thumbnail

NextJS ๊ณต์‹๋ฌธ์„œ ๐Ÿ‘

โš™๏ธ next.config.js

  • Next.js์—์„œ ์ปค์Šคํ…€ ๊ณ ๊ธ‰(?) ์„ค์ •์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ ๋ฃจํŠธ์— next.config.js ํŒŒ์ผ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
  • next.config.js๋Š” JSON ํŒŒ์ผ์ด ์•„๋‹Œ ์ผ๋ฐ˜ Node.js ๋ชจ๋“ˆ์ด๋‹ค.
  • Next.js ์„œ๋ฒ„ ๋ฐ ๋นŒ๋“œ ๋‹จ๊ณ„์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ ๋ธŒ๋ผ์šฐ์ € ๋นŒ๋“œ์—๋Š” ํฌํ•จ๋˜์ง€ ์•Š๋Š”๋‹ค.

next.config.js์—์„œ redirects์™€ rewrites ์„ค์ •์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.


๐Ÿค Redirects

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  async redirects() {
    return [
      {
        source: "/contact",
        destination: "/form",
        permanent: false,
      },
    ];
  },
};

module.exports = nextConfig;
  • redirects ์€ source, destination, permanent ์†์„ฑ์ด ์žˆ๋Š” ๊ฐ์ฒด ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜์ด๋‹ค.
    • source : request ๊ฒฝ๋กœ
    • destination : redirectํ•  ๊ฒฝ๋กœ
    • permanent : true or false
      • true์ธ ๊ฒฝ์šฐ ํด๋ผ์ด์–ธํŠธ์™€ search ์—”์ง„์— redirect๋ฅผ ์˜๊ตฌ์ ์œผ๋กœ cacheํ•˜๋„๋ก ์ง€์‹œํ•˜๋Š” 308 status code๋ฅผ ์‚ฌ์šฉ
      • false์ธ ๊ฒฝ์šฐ ์ผ์‹œ์ ์ด๊ณ  cache๋˜์ง€ ์•Š์€ 307 status code๋ฅผ ์‚ฌ์šฉ

๐Ÿ“Œ next.config.js์—์„œ redirects ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ source ๊ฒฝ๋กœ๋ฅผ destination ๊ฒฝ๋กœ๋กœ redirectํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • pattern matching
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  async redirects() {
    return [
      {
        source: "/old-blog/:path",
        destination: "/new-blog/:path",
        permanent: false,
      },
    ];
  },
};

module.exports = nextConfig;

// ex) localhost:3000/old-blog/11122 (request) -> localhost:3000/new-blog/11122 (redirect)
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  async redirects() {
    return [
      {
        source: "/old-blog/:path*",
        destination: "/new-blog/:path*",
        permanent: false,
      },
    ];
  },
};

module.exports = nextConfig;

// ex) localhost:3000/old-blog/11122/comments/11 (request) 
//     ->  localhost:3000/new-blog/11122/comments/11 (redirect)

๐Ÿ™ˆ Rewrites

/** @type {import('next').NextConfig} */

const API_KEY = process.env.API_KEY;

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

module.exports = nextConfig;
  • rewrites๋Š” source, destination ์†์„ฑ์„ ๊ฐ€์ง€๋Š” ๊ฐ์ฒด ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜์ด๋‹ค.
    • source: request ๊ฒฝ๋กœ
    • destination : routingํ•  ๊ฒฝ๋กœ

๐Ÿ“Œ next.config.js์—์„œ rewrites ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ source ๊ฒฝ๋กœ๋ฅผ destination ๊ฒฝ๋กœ์— ๋งคํ•‘ํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

โœจ Example
1. rewrites ์„ค์ • X

// next.config.js

/** @type {import('next').NextConfig} */

const API_KEY = process.env.API_KEY;

const nextConfig = {
  reactStrictMode: true,
};

module.exports = nextConfig;

rewrites ์„ค์ •์„ ํ•˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}๋กœ GET ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด ์•„๋ž˜ ์‚ฌ์ง„์— ๋ณด์ด๋“ฏ์ด API KEY๊ฐ€ ๊ทธ๋Œ€๋กœ ๋…ธ์ถœ์ด ๋œ๋‹ค.

  1. rewrites ์„ค์ • O
/** @type {import('next').NextConfig} */

const API_KEY = process.env.API_KEY;

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

module.exports = nextConfig;

http://locahost:3000/api/movies ํ˜น์€ api/movies๋กœ GET ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด rewrites ์„ค์ •์— ๋”ฐ๋ผ destination ๊ฒฝ๋กœ๋กœ ๋งคํ•‘์ด ๋˜์–ด https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}๋กœ GET ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค. ๋˜ํ•œ, API_KEY์˜ ๋…ธ์ถœ์„ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.๐Ÿ‘

๐Ÿ™Œ Rewrites vs Redirect

  • Rewrites์€ URL ํ”„๋ก์‹œ ์—ญํ• ์„ ํ•˜๊ณ  destination ๊ฒฝ๋กœ๋ฅผ source ๊ฒฝ๋กœ๋กœ maskํ•œ๋‹ค.
  • Redirects์€ source๊ฒฝ๋กœ๋ฅผ destination ๊ฒฝ๋กœ๋กœ redirect์‹œํ‚ค๊ณ , URL๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€