codinghatso

Learn Next.js 제 14장 : Improving Accessibility 본문

WEB/Next.js

Learn Next.js 제 14장 : Improving Accessibility

hatso 2025. 3. 13. 00:09

-ai를 사용해 개념정리 했음을 공지합니다.-

 

이번 장에서 배울 내용

* 사용 방법eslint-plugin-jsx-a11y Next.js와 함께 접근성 모범 사례를 구현합니다.
* 서버 측 양식 검증을 구현하는 방법.
* 반응 사용 방법useActionState 양식 오류를 처리하여 사용자에게 표시합니다.

useActionState

 

접근성이란 무엇인가 - What is accessibility?

접근성은 장애인을 포함한 모든 사람이 사용할 수 있는 웹 애플리케이션을 설계하고 구현하는 것을 말합니다.
키보드 내비게이션, 시맨틱 HTML, 이미지, 색상, 동영상 등 다양한 분야를 다루는 방대한 주제입니다.

이 과정에서는 접근성에 대해 자세히 설명하지 않습니다.
Next.js에서 제공하는 접근성 기능과 애플리케이션의 접근성을 높이기 위한 몇 가지 일반적인 관행에 대해 논의하겠습니다.

 

접근성에 대해 더 알고 싶다면 이 사이트를 참고하세요. https://web.dev/learn/accessibility/

 

Learn Accessibility  |  web.dev

An evergreen accessibility course and reference to level up your web development.

web.dev

 

ESlint를 사용하는 것 또한 접근성을 높이는 방법이라고 말한다.

//package.json
"scripts": {
    "build": "next build",
    "dev": "next dev",
    "start": "next start",
    "lint": "next lint"
},

사용법은 아래와 같지만 동작하지 않을 수도 있다. 기본적으로 lint는 next.js 패키지에 설치되어 있지만 없다면 따로 설치해야 한다.

설치 전에 package.json의 scripts에 "lint": "next lint" 구문을 추가해서 아래의 명령어를 실행해 보자.

처음 실행 시 패키지를 다운받는 형태가 나오는게 정상이다.

pnpm lint

처음 실행시 초기화 옵션이 나오는데 아래 설명을 읽고 상황에 맞는 옵션을 선택하면 된다.

📌 pnpm lint 실행 시 "strict" 또는 "base" 옵션이 나오는 이유

Next.js에서 pnpm lint를 실행할 때, ESLint 설정을 초기화해야 하는 경우
strict와 base 중 선택하라는 메시지가 나올 수 있어요.


✅ strict와 base의 차이

🔹 strict (엄격 모드)

  • 더 많은 코드 스타일 규칙과 접근성 검사를 적용
  • base보다 더 엄격한 린팅 규칙을 사용하며, 코드 품질을 더 철저하게 관리할 수 있음
  • 추천 대상: 협업 프로젝트, 코드 품질이 중요한 경우

🔹 base (기본 모드)

  • 기본적인 ESLint 규칙만 적용 (strict보다 완화된 규칙)
  • Next.js의 필수적인 규칙만 포함하며, 엄격한 코드 스타일 검사는 하지 않음
  • 추천 대상: 간단한 프로젝트, 최소한의 코드 검사만 필요한 경우

✅ 어느 옵션을 선택해야 할까?

  • 코드 품질을 철저히 관리하고 싶다면?strict 선택
  • 기본적인 린팅만 필요하고, 강제적인 스타일 규칙을 원하지 않는다면?base 선택

✅ 예제: strict 모드 선택 후 ESLint 설정 파일 생성

pnpm lint

🔹 Would you like to use strict or base ESLint configuration?
🔹 strict를 입력하고 Enter

🚀 이후 .eslintrc.json 파일이 생성되며, ESLint 설정이 적용됨!


✅ 결론

strict → 엄격한 코드 스타일 검사, 협업 및 유지보수에 유리
base → 기본 규칙만 적용, 가벼운 린팅 필요 시 선택

💡 개인 프로젝트라면 base, 팀 프로젝트라면 strict를 추천! 😊

 

 

참고로 나는 base 모드를 선택했다. 과정에서 lint를 사용하면 어떤 식으로 코드를 관리할 수 있는지 알려주니 따라 하면 된다.


📌 폼(Form) 접근성 개선

Next.js 14장에서는 폼을 더 쉽게 사용할 수 있도록 "접근성을 향상시키는 방법"을 설명하고 있어요.
현재 우리가 3가지 방법을 이미 적용하고 있는데, 그것들을 쉽게 풀어서 정리해 볼게요! 🚀


✅ 1. <input> 같은 적절한 태그 사용

잘못된 예시 (사용하면 안 됨)

<div>이름 입력</div> 

올바른 예시 (사용해야 함)

<input type="text" placeholder="이름을 입력하세요" />
  • 의미 있는 태그(<input>, <option> 등)를 사용해야 함.
  • div 같은 일반 태그는 보조기술(스크린 리더 등)이 폼 요소로 인식하지 못함.
  • <input>을 사용하면 보조기술(AT, Assistive Technologies)이 내용을 정확하게 읽어줌.

✅ 2. <label> 태그와 htmlFor 속성 사용

잘못된 예시 (사용하면 안 됨)

<input type="text" id="name" />

올바른 예시 (사용해야 함)

<label htmlFor="name">이름</label>
<input type="text" id="name" />
  • <label>을 사용하면 입력란(input)에 대한 설명을 제공할 수 있음.
  • 보조기술(스크린 리더 등)이 "이름"이라는 정보를 정확하게 전달할 수 있음.
  • 사용자가 <label>을 클릭하면 자동으로 해당 입력란이 활성화됨 → 사용성 향상!

✅ 3. 키보드(Tab 키)로 폼 이동 가능

  • <input>, <button> 등을 사용하면, 사용자가 Tab 키를 눌러 쉽게 폼 요소를 이동할 수 있음.
  • div처럼 의미 없는 태그를 쓰면, Tab으로 이동할 수 없음.
  • 키보드를 사용하는 사용자에게 중요한 기능!

📌 결론

폼 요소(<input>, <option>)를 적절히 사용해야 보조기술이 이해할 수 있음.
<label>과 htmlFor 속성을 사용하면 폼 필드를 쉽게 클릭하고 이해할 수 있음.
Tab 키를 사용하여 폼을 쉽게 이동할 수 있도록 구성해야 함.

🚀 즉, 이 3가지를 적용하면 폼을 더 많은 사용자(스크린 리더 사용자, 키보드 유저 등)에게 접근 가능하게 만들 수 있어요! 😊

 

Form 검증

Form 검증하는 방식에 대해 두 가지 관점으로 설명하고 있다.

클라이언트 측 검증

브라우저의 기능을 사용해서 검증하는 방식 채용

<input
  id="amount"
  name="amount"
  type="number"
  placeholder="Enter USD amount"
  className="peer block w-full rounded-md border border-gray-200 py-2 pl-10 text-sm outline-2 placeholder:text-gray-500"
  required
/>

 

서버 측 검증

zod 라이브러리를 활용해서 유효한 데이터가 어떤 데이터인지 설정함.

📌 Next.js에서 서버측 검증(Server-side Validation) 적용하기

Next.js에서는 서버에서 데이터 검증을 수행하여 보안과 데이터 무결성을 보장할 수 있습니다. 이를 위해 Zod 라이브러리를 활용한 서버측 검증을 적용할 수 있습니다.


✅ 서버측 검증이 필요한 이유

  • 클라이언트 측 검증만으로는 보안이 충분하지 않음 → 사용자가 브라우저 개발자 도구에서 값을 조작할 수 있음.
  • 서버에서 데이터를 검증하면 신뢰할 수 있는 데이터만 데이터베이스에 저장 가능.

✅ 서버측 검증 적용 방법 (Zod 활용)

1️⃣ Zod 스키마를 정의하여 입력값 검증

import { z } from "zod";

const FormSchema = z.object({
  customerId: z.string().min(1, "Please select a customer."),
  amount: z.coerce.number().gt(0, "Amount must be greater than $0."),
  status: z.enum(["pending", "paid"]),
});
  • customerId → 필수 값
  • amount → 숫자로 변환 후, 0보다 큰 값만 허용
  • status → "pending" 또는 "paid" 값만 가능

2️⃣ 폼 데이터 검증 후 처리 (safeParse 활용)

export async function createInvoice(formData: FormData) {
  const validatedFields = FormSchema.safeParse({
    customerId: formData.get("customerId"),
    amount: formData.get("amount"),
    status: formData.get("status"),
  });

  if (!validatedFields.success) {
    return {
      errors: validatedFields.error.flatten().fieldErrors,
      message: "Invalid input data.",
    };
  }

  const { customerId, amount, status } = validatedFields.data;
  // 데이터베이스 저장 로직 실행...
}
  • safeParse()를 사용하여 데이터 검증 후, 성공 여부를 확인.
  • 유효하지 않은 경우 오류 메시지를 반환하고, 데이터 저장을 방지.

✅ 결론

서버측 검증은 보안을 강화하고 데이터 무결성을 보장
Zod를 활용하여 간단하고 강력한 데이터 검증 적용 가능
폼 입력값을 서버에서 검증하여 잘못된 데이터 저장 방지

🚀 즉, 서버측 검증을 추가하면 보안이 강화되고, 신뢰할 수 있는 데이터만 처리할 수 있습니다! 😊

 

마지막으로 "보이스 스크린" 기능으로 시각 장애인 분들이 웹 서비스를 사용할 때 용이할 수 있도록 설정하는 법을 알려줍니다.

aria-label 속성을 input 태그에 사용하면 사용자에게 소리로 aria-label의 내용을 읽어줍니다.

 

Comments