treeru.com
개발

Next.js로 관리자 페이지 만들기 — 실전 어드민 패널 구축기

2026-02-06
Treeru

자체 서비스를 운영하다 보면 관리자 페이지가 반드시 필요합니다. 회원 관리, 콘텐츠 관리, SEO 현황, 성능 모니터링 등 — 직접 DB를 들여다보는 것보다어드민 패널을 만들어두면 운영 효율이 몇 배로 올라갑니다. Next.js로 실전에서 쓸 수 있는 어드민 패널을 구축하는 과정을 정리했습니다.

사이드바

네비게이션

역할 기반

접근 제어

RESTful

API 설계

원클릭

주요 작업

1어드민 패널 아키텍처

어드민 패널을 별도 프로젝트로 분리할지, 메인 사이트 내에 포함할지가 첫 번째 결정입니다. 각각 장단점이 있으며, 프로젝트 규모에 따라 선택이 달라집니다.

구조장점단점적합한 경우
메인 사이트 내 /admin 경로코드 공유, 배포 단순번들 크기 증가소규모 프로젝트
별도 Next.js 프로젝트독립 배포, 권한 분리코드 중복, 관리 포인트 증가중규모 이상
서브도메인 (admin.example.com)완전 분리, 보안 강화CORS 설정, 인증 공유팀 단위 개발

별도 프로젝트로 분리하는 것을 권장합니다

메인 사이트와 어드민을 분리하면 메인 사이트의 빌드 크기에 영향을 주지 않고, 독립적으로 배포할 수 있습니다. DB와 인증은 공유하되, 프론트엔드는 분리하는 것이 깔끔합니다.

2UI 프레임워크 선택

어드민 패널은 사용자에게 보이지 않으므로 화려한 디자인보다 기능성과 개발 속도가 우선입니다. Tailwind CSS + shadcn/ui 조합이 빠른 개발과 일관된 UI를 제공합니다.

어드민 사이드바 레이아웃 구조

// app/admin/layout.tsx
export default function AdminLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="flex min-h-screen">
      {/* 사이드바: 고정 너비, 스크롤 독립 */}
      <aside className="w-64 bg-sidebar border-r
                        flex-shrink-0 overflow-y-auto">
        <AdminSidebar />
      </aside>

      {/* 메인 콘텐츠 영역 */}
      <main className="flex-1 p-6 overflow-y-auto">
        {children}
      </main>
    </div>
  );
}

어드민 사이드바 필수 메뉴

대시보드 (개요)
회원 관리
콘텐츠 관리
SEO 관리
PageSpeed 측정
이메일 발송
설정
로그아웃

3페이지 관리 구조

Next.js의 App Router를 활용하면 어드민 페이지를 체계적으로 구성할 수 있습니다. 각 기능을 별도 라우트로 분리하고, 공통 레이아웃을 적용합니다.

어드민 라우트 구조

app/admin/
  layout.tsx          # 사이드바 + 메인 레이아웃
  page.tsx            # 대시보드 (통계 요약)
  members/
    page.tsx          # 회원 목록 + 검색
    [id]/page.tsx     # 회원 상세/수정
  content/
    page.tsx          # 콘텐츠 관리
  seo/
    page.tsx          # SEO 현황 (IndexNow 등)
  pagespeed/
    page.tsx          # PageSpeed 측정 결과
  email/
    page.tsx          # 이메일 발송
  settings/
    page.tsx          # 서비스 설정

대시보드 페이지 예시

// app/admin/page.tsx
export default async function AdminDashboard() {
  const stats = await getAdminStats();

  return (
    <div>
      <h1 className="text-2xl font-bold mb-6">대시보드</h1>
      <div className="grid grid-cols-4 gap-4">
        <StatCard label="전체 회원" value={stats.totalMembers} />
        <StatCard label="오늘 방문자" value={stats.todayVisitors} />
        <StatCard label="블로그 글" value={stats.totalPosts} />
        <StatCard label="평균 PageSpeed" value={stats.avgPageSpeed} />
      </div>
    </div>
  );
}

4인증 미들웨어

어드민 페이지에 아무나 접근할 수 없도록 미들웨어에서 인증을 검사해야 합니다. Next.js의 middleware.ts에서 /admin 경로를 보호하면 모든 어드민 페이지가 자동으로 보호됩니다.

middleware.ts — 어드민 경로 보호

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;

  // /admin 경로 보호
  if (pathname.startsWith("/admin")) {
    const sessionCookie = request.cookies.get("better-auth.session_token");

    if (!sessionCookie) {
      return NextResponse.redirect(
        new URL("/auth/login", request.url)
      );
    }

    // 세션 유효성은 서버 컴포넌트에서 추가 검증
  }

  return NextResponse.next();
}

export const config = {
  matcher: ["/admin/:path*"],
};

미들웨어만으로는 충분하지 않습니다

미들웨어에서는 쿠키 존재 여부만 체크하고, 실제 세션 유효성과 관리자 권한은 서버 컴포넌트나 API 라우트에서 DB를 조회하여 확인해야 합니다. 미들웨어는 첫 번째 관문이고, 실제 인증/인가는 두 번째 관문에서 처리합니다.

5API 라우트 설계

어드민 패널의 데이터 조회와 수정은 API 라우트를 통해 처리합니다. RESTful 패턴을 따르면 일관성 있는 API를 만들 수 있습니다.

API 라우트 구조

app/api/admin/
  members/
    route.ts           # GET: 목록, POST: 생성
    [id]/
      route.ts         # GET: 상세, PUT: 수정, DELETE: 삭제
  pagespeed/
    route.ts           # POST: 측정 실행
    results/
      route.ts         # GET: 측정 결과 조회
  indexnow/
    route.ts           # POST: URL 제출
    history/
      route.ts         # GET: 제출 이력

회원 관리 API 예시

// app/api/admin/members/route.ts
import { adminGuard } from "@/lib/admin-auth";
import { db } from "@/lib/db";
import { users } from "@/lib/db/schema";

export async function GET(req: Request) {
  const session = await adminGuard();
  if (session instanceof NextResponse) return session;

  const { searchParams } = new URL(req.url);
  const page = Number(searchParams.get("page")) || 1;
  const limit = 20;

  const members = await db
    .select()
    .from(users)
    .limit(limit)
    .offset((page - 1) * limit)
    .orderBy(users.createdAt);

  return NextResponse.json({ members, page, limit });
}
HTTP 메서드경로동작
GET/api/admin/members회원 목록 조회
POST/api/admin/members회원 생성
GET/api/admin/members/[id]회원 상세 조회
PUT/api/admin/members/[id]회원 정보 수정
DELETE/api/admin/members/[id]회원 삭제

6외부 서비스 연동

어드민 패널의 진짜 가치는 외부 서비스를 한곳에서 관리할 수 있다는 것입니다.PageSpeed API 자동화, IndexNow, 이메일 발송 등을 어드민 UI에 통합하면 운영 효율이 크게 올라갑니다.

연동 서비스어드민 기능효과
PageSpeed Insights API전체 페이지 성능 측정성능 저하 조기 발견
IndexNowURL 색인 요청, 이력 조회검색 노출 가속
이메일 SMTP뉴스레터, 알림 발송사용자 리텐션
Google Analytics트래픽 요약 대시보드의사결정 데이터

어드민 패널은 계속 성장합니다

처음에는 회원 관리와 콘텐츠 관리만으로 시작하고, 운영하면서 필요한 기능을 하나씩 추가하는 것이 좋습니다. 처음부터 모든 기능을 구현하려 하면 출시가 늦어집니다. MVP 마인드로 접근하세요.

요약 체크리스트

어드민 패널 구축 핵심 요약

  • 메인 사이트와 어드민을 별도 프로젝트로 분리하는 것을 권장한다
  • Tailwind + shadcn/ui로 빠르게 일관된 UI를 구성한다
  • 사이드바 + 콘텐츠 영역 레이아웃을 기본 구조로 사용한다
  • 미들웨어에서 /admin 경로를 보호하고, API에서 권한을 이중 검증한다
  • RESTful API 패턴으로 CRUD 엔드포인트를 구성한다
  • 외부 서비스 연동은 MVP 기능부터 단계적으로 추가한다

본 글은 Next.js 15 App Router 기준으로 작성되었습니다. 어드민 패널의 보안은 특히 중요하므로, 인증/인가 로직에 대해 반드시 보안 리뷰를 받으시기 바랍니다. 본 콘텐츠의 비상업적 공유는 자유이나, 상업적 이용 시 문의 페이지를 통해 연락 바랍니다.

관리자 페이지 개발이 필요하신가요?

Treeru는 Next.js 기반 어드민 패널, 회원 관리, API 설계, 인증 시스템까지 풀스택으로 구축해 드립니다.

어드민 개발 상담 신청
T

Treeru

웹 개발, IT 인프라, AI 솔루션 분야의 실무 인사이트를 공유합니다. 기업의 디지털 전환을 돕는 IT 파트너, Treeru입니다.

공유

댓글

(4개)
4.63/ 5

로그인하면 댓글을 작성할 수 있습니다.

2026-02-19
555.0

인증 미들웨어 패턴이 깔끔합니다. 모든 /admin 경로에 자동으로 적용되니까 빠뜨리는 실수가 없어요.

2026-02-16
4.554.5

API 라우트 설계 부분이 특히 유용했습니다. RESTful 패턴으로 CRUD를 구성하면서도 Next.js에 맞게 최적화한 것이 실전적이에요.

2026-02-13
454.0

외부 어드민 서비스(Retool, Forest Admin 등) 대신 자체 구축하는 장단점을 잘 정리해주셨어요. 우리 팀도 자체 구축 쪽으로 결정했습니다.

관련 글

© 2026 TreeRU. All rights reserved.

본 콘텐츠의 저작권은 TreeRU에 있으며, 출처를 밝히지 않은 무단 전재 및 재배포를 금합니다. 인용 시 출처(treeru.com)를 반드시 명시해 주세요.