Next.js로 관리자 페이지 만들기 — 실전 어드민 패널 구축기
자체 서비스를 운영하다 보면 관리자 페이지가 반드시 필요합니다. 회원 관리, 콘텐츠 관리, 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>
);
}어드민 사이드바 필수 메뉴
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 | 전체 페이지 성능 측정 | 성능 저하 조기 발견 |
| IndexNow | URL 색인 요청, 이력 조회 | 검색 노출 가속 |
| 이메일 SMTP | 뉴스레터, 알림 발송 | 사용자 리텐션 |
| Google Analytics | 트래픽 요약 대시보드 | 의사결정 데이터 |
어드민 패널은 계속 성장합니다
처음에는 회원 관리와 콘텐츠 관리만으로 시작하고, 운영하면서 필요한 기능을 하나씩 추가하는 것이 좋습니다. 처음부터 모든 기능을 구현하려 하면 출시가 늦어집니다. MVP 마인드로 접근하세요.
요약 체크리스트
어드민 패널 구축 핵심 요약
- ✓메인 사이트와 어드민을 별도 프로젝트로 분리하는 것을 권장한다
- ✓Tailwind + shadcn/ui로 빠르게 일관된 UI를 구성한다
- ✓사이드바 + 콘텐츠 영역 레이아웃을 기본 구조로 사용한다
- ✓미들웨어에서 /admin 경로를 보호하고, API에서 권한을 이중 검증한다
- ✓RESTful API 패턴으로 CRUD 엔드포인트를 구성한다
- ✓외부 서비스 연동은 MVP 기능부터 단계적으로 추가한다
본 글은 Next.js 15 App Router 기준으로 작성되었습니다. 어드민 패널의 보안은 특히 중요하므로, 인증/인가 로직에 대해 반드시 보안 리뷰를 받으시기 바랍니다. 본 콘텐츠의 비상업적 공유는 자유이나, 상업적 이용 시 문의 페이지를 통해 연락 바랍니다.
댓글
(4개)로그인하면 댓글을 작성할 수 있습니다.
인증 미들웨어 패턴이 깔끔합니다. 모든 /admin 경로에 자동으로 적용되니까 빠뜨리는 실수가 없어요.
API 라우트 설계 부분이 특히 유용했습니다. RESTful 패턴으로 CRUD를 구성하면서도 Next.js에 맞게 최적화한 것이 실전적이에요.
외부 어드민 서비스(Retool, Forest Admin 등) 대신 자체 구축하는 장단점을 잘 정리해주셨어요. 우리 팀도 자체 구축 쪽으로 결정했습니다.
관련 글
© 2026 TreeRU. All rights reserved.
본 콘텐츠의 저작권은 TreeRU에 있으며, 출처를 밝히지 않은 무단 전재 및 재배포를 금합니다. 인용 시 출처(treeru.com)를 반드시 명시해 주세요.