๐Ÿ’ฃ Next.js_04 Custom Error Page, Environment Variables

qhflrnfl4324ยท2022๋…„ 1์›” 28์ผ
3

Next.js

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

Next.js

์ฝ”๋”ฉ์•™๋งˆ Next.js ๊ฐ•์˜๋ฅผ ๋ณด๊ณ  ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

๐Ÿ”ช Custom Error Page

404 error

  • 404 page๋Š” ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์—๋Ÿฌ ํŽ˜์ด์ง€
    => ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์—๋Ÿฌ ํŽ˜์ด์ง€๋ฅผ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง ํ•˜๋ฉด ์„œ๋ฒ„์˜ ๋ถ€ํ•˜๊ฐ€ ์ฆ๊ฐ€
    => ์ด๋กœ์ธํ•ด ๋น„์šฉ์ด ์ฆ๊ฐ€ํ•˜๊ณ , ์‚ฌ์šฉ์ž๋“ค์€ ๋Š๋ฆฌ๋‹ค๋Š” ๋Š๋‚Œ์„ ๋ฐ›๋Š”๋‹ค.
  • Next.js๋Š” static 404 page๋ฅผ ์ œ๊ณต
    => ์•„๋ฌด๋Ÿฐ ์ถ”๊ฐ€ ์ž‘์—… ์—†์ด default๋กœ ์ œ๊ณต๋˜๋Š” ํŽ˜์ด์ง€๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    => ๋””์ž์ธ์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ๊ฑฐ๋‚˜ ๊ธฐํƒ€ ๋‹ค๋ฅธ ์ •๋ณด๋“ค๋„ ํ•จ๊ป˜ ํฌํ•จํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ, ์ˆ˜์ •์ด ํ•„์š”

Customizing The 404 Page

  • pages/404.js ํŒŒ์ผ ์ƒ์„ฑ
    => ์ด ํŒŒ์ผ์€ build time์— ์ •์  ์ƒ์„ฑ
// pages/404.js
export default function Custom404() {
  return <h1>404 - Page Not Found</h1>
}

// customizing
import { Icon } from "semantic-ui-react";

export default function Error404() {
  return (
    <div style={{ padding: "20px 0 ", textAlign: "center", fontSize: 30 }}>
      <Icon name="warning circle" color="red" />
      404: ํŽ˜์ด์ง€๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
    </div>
  );
}

500 error

  • 500 page๋„ 404 page์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Next.js์—์„œ static 500 page๋ฅผ ์ œ๊ณต

๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ๋Š” ์„œ๋ฒ„ ์—๋Ÿฌ๊ฐ€ ๋‚˜๋ฉด ๋กœ๊ทธ๋ฅผ ๋ณด์—ฌ์คŒ
=> ์–ด๋””์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์•Œ๋ ค์คŒ

  • 500 error(์„œ๋ฒ„ ์—๋Ÿฌ)๋Š” ํ”„๋กœ๋•์…˜ ๋ชจ๋“œ์—์„œ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค
    => ํ”„๋กœ๋•์…˜ ๋ชจ๋“œ : build๋ฅผ ํ•œ ํ›„start๋ฅผ ํ•œ๋‹ค.
    => ๋‚ด ๊ฒฝ์šฐ, yarn build, yarn start
    => 500 error ํ™•์ธ

More Advanced Error Page Customizing

  • Error component๋กœ client-side error์™€ server-side error๋ฅผ ๋ชจ๋‘ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
    => _error.js ํŽ˜์ด์ง€๋Š” ์ •์ ์œผ๋กœ ์ตœ์ ํ™” ๋˜์–ด์žˆ์ง€ ์•Š๋‹ค.
    => 404๋Š” static์œผ๋กœ ์ฒ˜๋ฆฌ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค

  • pages/_error.js ํŒŒ์ผ ์ƒ์„ฑ

// _error.js
function Error({ statusCode }) {
  return (
    <p>
      {statusCode
        ? `An error ${statusCode} occurred on server`
        : 'An error occurred on client'}
    </p>
  )
}

Error.getInitialProps = ({ res, err }) => {
  const statusCode = res ? res.statusCode : err ? err.statusCode : 404
  return { statusCode }
}

export default Error

  • server-side error page๋ฅผ ์ •์ ์œผ๋กœ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ์ด์œ ? => ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ์„œ๋ฒ„ ์ชฝ์œผ๋กœ ์—๋Ÿฌ๋ฅผ ๋ณด๋‚ด๋Š” ์ž‘์—…์„ ๋™๋ฐ˜ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ

๐Ÿ”ช Environment Variables

  • ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ๋ณ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’๋“ค์„ ๋ถ„๊ธฐ ์ฒ˜๋ฆฌ
    => ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋Š” A ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋ณด์—ฌ์•ผ ํ•˜์ง€๋งŒ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” B ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋ณด์—ฌ์ ธ์•ผ ํ•˜๋Š” ๊ฒƒ ๋“ฑ
    => ํ…Œ์ŠคํŠธ๋กœ ์šด์˜ํ•˜๋˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์‹ค์ œ ์„œ๋น„์Šค์— ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด

    • .env : ๋ชจ๋“  ํ™˜๊ฒฝ
    • .env.development : ๊ฐœ๋ฐœ ํ™˜๊ฒฝ
    • .env.production : ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ

    => ์ตœ์ƒ์œ„ ํด๋”์— ํŒŒ์ผ ์ƒ์„ฑ

์‚ฌ์šฉ๋ฒ•

Environment Variables Examples

  • ํ™˜๊ฒฝ๋งˆ๋‹ค ์‚ฌ์šฉ๋ฒ•์ด ๋‹ค๋ฆ„
// node js
process.env.๋ณ€์ˆ˜๋ช…;

// browser
process.env.NEXT_PUBLIC_๋ณ€์ˆ˜๋ช…;
//.env.development
// name : ๋…ธ๋“œ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉ
// NEXT_PUBLIC_API_URL : ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉ
name=DEVELOPMENT
NEXT_PUBLIC_API_URL=http://makeup-api.herokuapp.com/api/v1/products.json?brand=maybelline
// .env.production
// ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์— ๋”ฐ๋ผ API ๊ฒฝ๋กœ๋ฅผ ๊ตฌ๋ถ„ํ•ด์„œ ์ƒํ’ˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋‹ค๋ฅด๊ฒŒ ๋‚˜์˜ค๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค
// .env.development์˜ API url๊ณผ ๋‹ค๋ฅธ url
name=PRODUCTION
NEXT_PUBLIC_API_URL=http://makeup-api.herokuapp.com/api/v1/products.json?brand=dior
  • browser ํ™˜๊ฒฝ์—์„œ NEXT_PUBLIC_API_URL ๋ณ€์ˆ˜ ๋ถ„๊ธฐ์ฒ˜๋ฆฌ
    • pages/index.js ์˜ API_URL ์ˆ˜์ •
      => ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์ด๋ผ์„œ NEXT_PUBLIC_API_URL๋ฅผ ์‚ฌ์šฉ
// const API_URL =
//   "http://makeup-api.herokuapp.com/api/v1/products.json?brand=maybelline";
const API_URL = process.env.NEXT_PUBLIC_API_URL;
  • node js ํ™˜๊ฒฝ์—์„œ name ๋ณ€์ˆ˜๋ฅผ ๋ถ„๊ธฐ์ฒ˜๋ฆฌ
    • getServerSideProps : ์„œ๋ฒ„์—์„œ ๋™์ž‘ (๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์ด ์•„๋‹ˆ๋‹ค)
import Axios from "axios";
import Head from "next/head";
import Item from "../../src/component/Item";

//  getServerSideProps๋ฅผ ํ†ตํ•ด item์„ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ
// name๋„ ๋ฐ›์•„์˜จ๋‹ค
const Post = ({ item, name }) => {
  return (
    <>
      {item && (
        <>
          <Head>
            <title>{item.name}</title>
            <meta name="description" content="item.description"></meta>
          </Head>
          // name์„ ํ†ตํ•ด ์–ด๋–ค ํ™˜๊ฒฝ์ธ์ง€ ํ™•์ธ
          <p>{name} ํ™˜๊ฒฝ ์ž…๋‹ˆ๋‹ค.</p>
          <Item item={item} />
        </>
      )}
    </>
  );
};

export default Post;

// getServerSideProps๋กœ ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ด
export async function getServerSideProps(context) {
  const id = context.params.id;
  const apiUrl = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`;
  const res = await Axios.get(apiUrl);
  const data = res.data;

  return {
    props: {
      item: data,
      name: process.env.name, // props๋กœ name ์ถ”๊ฐ€
    },
  };
}
  • ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ๋ณด์—ฌ์ฃผ๋Š” ๋ฐ์ดํ„ฐ

  • ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ ๋ณด์—ฌ์ฃผ๋Š” ๋ฐ์ดํ„ฐ

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

comment-user-thumbnail
2022๋…„ 1์›” 28์ผ

์šฐ์•„ใ…ใ…ใ…ใ…

1๊ฐœ์˜ ๋‹ต๊ธ€