본문으로 건너뛰기
블록

404 페이지

페이지를 찾지 못했을 때 보여 주는 블록이에요. 4, 0, 4를 도형으로 쓴 일러스트와 돌아갈 길을 함께 안내해요.

  • #arc
  • #block
  • #404
  • #not-found
  • #error
  • #illustration
  • #page

설치

이 명령 한 줄이면 필요한 파일과 패키지가 함께 설치돼요.

터미널bash
npx shadcn@latest add https://dsui.vercel.app/r/not-found.json

not-found.module.csscss
.notFound { display: flex; width: 100%; max-width: 36rem; margin-inline: auto; flex-direction: column; align-items: center; text-align: center; word-break: keep-all; color: var(--foreground); font-family: var(--font-body); letter-spacing: var(--tracking-body); }
.art { width: min(100%, 520px); margin-block-end: var(--space-4); border-radius: var(--radius-surface); }
.title { margin: 0; color: var(--foreground); font-family: var(--font-display); font-size: var(--text-2xl); font-weight: 500; letter-spacing: var(--tracking-display); line-height: 1.3; text-wrap: balance; }
.description { max-width: 24rem; margin: var(--space-3) 0 0; color: var(--text-secondary); font-size: var(--text-sm); line-height: var(--leading-body); text-wrap: balance; }
.actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-2); margin-top: var(--space-6); }
not-found.tsxtsx
"use client";

import type { HTMLAttributes, ReactNode } from "react";
import { ButtonLink } from "../../button-link/button-link";
import { Illustration } from "../../illustration/illustration";
import styles from "./not-found.module.css";

export interface NotFoundProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
  title?: string;
  description?: ReactNode;
  /** The ways out, centred under the text. Left out, one link back to `homeHref`. */
  actions?: ReactNode;
  /** Where the default action goes. */
  homeHref?: string;
  /** The heading level. Default 1: a 404 page is usually the whole page, and the heading is its title. */
  headingLevel?: 1 | 2 | 3;
  /** Draws the 404 page-top illustration above the title. The theme's own art is used when it has one. Default true. */
  illustration?: boolean;
}

/**
 * The page a reader lands on when the link is broken or the page has moved. It says plainly what happened, not whose fault
 * it is, and gives a way out right away. The 404 page-top illustration spells 4-0-4 in shapes, in the theme's colours.
 *
 * The heading level is yours: on a real 404 page it is the h1, inside another page it is lower.
 */
export function NotFound({
  className,
  title = "페이지를 찾을 수 없어요",
  description = "주소가 바뀌었거나 없어진 페이지예요. 홈에서 다시 찾아볼까요?",
  actions,
  homeHref = "/",
  headingLevel = 1,
  illustration = true,
  ...props
}: NotFoundProps) {
  const Heading = `h${headingLevel}` as "h1" | "h2" | "h3";
  return (
    <section {...props} className={[styles.notFound, className].filter(Boolean).join(" ")}>
      {illustration ? <Illustration name="page-404" animated className={styles.art} /> : null}
      <Heading className={styles.title}>{title}</Heading>
      {description ? <p className={styles.description}>{description}</p> : null}
      <div className={styles.actions}>{actions ?? <ButtonLink href={homeHref}>홈으로 가기</ButtonLink>}</div>
    </section>
  );
}

NotFound.displayName = "NotFound";

export default NotFound;

사용된 항목