reopt designreopt design
DocsExploreToolsPricingBuilder
Start
Overview
Start
Core Concepts
Core Concepts
Surface
Surface 카탈로그
Build & Operate
서버 계약
Production readiness
Obrandapp-ui
reopt designreopt design

A design system for the AI era

  • Docs
  • Pricing
  • Releases
  • GitHub
  • Terms of Service
  • Privacy Policy

© 2026 reopt-ai. All rights reserved.

Start
  1. Docs
  2. /
  3. Start
  4. /
  5. brandapp-ui 시작하기

brandapp-ui 시작하기

brandapp-sdk foundation을 먼저 만들고 opt surface add로 필요한 UI 소스만 복사하는 빠른 시작 가이드입니다.

reopt design · Updated Jun 26, 2026

개요시작하기핵심 개념Surface 카탈로그서버 계약Production readiness

1. 설치 모델

brandapp-ui는 npm runtime component가 아니라 copy-paste Surface source입니다. Surface는 소비자 프로젝트의 @/lib/auth-client, API route, opt-ui theme를 전제로 동작합니다.

SDK가 로직 소유

OAuth, session, EAV, AI credit, typed error는 @reopt-ai/brandapp-sdk가 담당합니다.

Surface는 조립 소유

Button, Avatar, DataTable, opt-chat 등을 제품 UI로 묶습니다.

소비자가 최종 소유

복사 후 copy, loading, empty, server route 정책을 프로젝트 기준으로 수정합니다.

2. 환경 변수

Reopt Studio에서 BrandApp과 OAuth client를 만들고, consumer app의 환경 변수에 client id, client secret, brandapp id를 설정합니다. secret은 서버 전용입니다.

bash
# apps/web/.env.local
BRANDAPP_CLIENT_ID=...
BRANDAPP_CLIENT_SECRET=...
BRANDAPP_ID=...

BETTER_AUTH_SECRET=...
BETTER_AUTH_URL=http://localhost:3000

3. SDK foundation

권장 경로는 brandapp-sdk-init 스킬로 lib/auth.ts, lib/auth-client.ts, auth route, error helper를 생성하는 것입니다. 수동 구성 시 최소 파일은 아래와 같습니다.

ts
// lib/auth.ts
import { betterAuth } from "better-auth";
import { nextCookies } from "better-auth/next-js";
import { createReoptBetterAuth } from "@reopt-ai/brandapp-sdk/better-auth";

const reopt = createReoptBetterAuth({
  clientId: process.env.BRANDAPP_CLIENT_ID!,
  clientSecret: process.env.BRANDAPP_CLIENT_SECRET!,
  brandappId: process.env.BRANDAPP_ID!,
  additionalScopes: ["offline_access"],
});

export const auth = betterAuth({
  baseURL: process.env.BETTER_AUTH_URL,
  secret: process.env.BETTER_AUTH_SECRET!,
  database: reopt.database,
  plugins: [nextCookies(), reopt.oauth],
});
ts
// lib/auth-client.ts
"use client";

import { createAuthClient } from "better-auth/react";
import {
  createReoptOAuthClient,
  REOPT_PROVIDER_ID,
} from "@reopt-ai/brandapp-sdk/better-auth/client";

export const authClient = createAuthClient({
  plugins: [createReoptOAuthClient()],
});

export async function signInWithReopt(callbackURL = "/") {
  return authClient.signIn.oauth2({
    providerId: REOPT_PROVIDER_ID,
    callbackURL,
  });
}

export async function signOut() {
  await authClient.signOut();
}
ts
// app/api/auth/[...all]/route.ts
import { toNextJsHandler } from "better-auth/next-js";
import { auth } from "@/lib/auth";

export const { GET, POST } = toNextJsHandler(auth.handler);

4. Surface 설치

필요한 Surface만 복사합니다. 인증 기본 세트는 4개이고, AI/EAV 화면은 서버 계약을 먼저 확인한 뒤 추가합니다.

bash
opt surface add sign-in-with-reopt-button
opt surface add reopt-user-menu
opt surface add sign-in-gate
opt surface add session-expired-dialog

# AI/EAV 화면까지 바로 시작할 때
opt surface add reopt-ai-chat reopt-ai-image-studio reopt-record-table

5. Header와 보호 화면에 연결

tsx
// app/(app)/layout.tsx 또는 Header 컴포넌트
import { ReoptUserMenu } from "@/components/reopt-user-menu";
import { SessionExpiredDialog } from "@/components/session-expired-dialog";

export function AppHeader() {
  return (
    <header className="flex items-center justify-between">
      <span>Workspace</span>
      <ReoptUserMenu callbackURL="/dashboard" />
      <SessionExpiredDialog callbackURL="/dashboard" />
    </header>
  );
}
tsx
// 보호된 페이지를 SignInGate로 감싸기
import { SignInGate } from "@/components/sign-in-gate";

export default function BillingPage() {
  return (
    <SignInGate
      title="결제 정보는 로그인이 필요합니다"
      description="구독 상태를 보려면 Reopt 계정으로 로그인해주세요."
      callbackURL="/billing"
    >
      <BillingDashboard />
    </SignInGate>
  );
}

6. 현재 Surface

전체 라이브 프리뷰는 /explore/brandapp-ui에서 확인합니다.

Auth & session

SignInWithReoptButton

authClient.signIn.oauth2()를 감싼 단일 CTA. ReoptSignInError code를 토스트 copy로 매핑하고 retry/help action을 제공합니다.

ReoptUserMenu

authClient.useSession() 상태에 따라 SkeletonAvatar, 로그인 버튼, Avatar + Dropdown 로그아웃 메뉴를 분기합니다.

SignInGate

보호된 화면을 children으로 감싸고 pending, signed-out, signed-in 상태를 분기합니다. fallback/loadingFallback으로 제품별 UI를 덮어쓸 수 있습니다.

SessionExpiredDialog

세션 truthy to falsy 전이 또는 reopt:session-expired window event를 받아 전역 재로그인 dialog를 엽니다.

AI surfaces

ReoptAiChat

opt-chat useChatSession과 DefaultChatTransport를 쓰는 풀스택 채팅 UI. modelsEndpoint, agentsEndpoint, creditsEndpoint를 선택적으로 연결합니다.

ReoptAiImageStudio

sdk.ai.generateImage 결과 URL을 렌더하는 text-to-image studio. image model selector, aspect ratio, style, recent history를 제공합니다.

Data & operations

ReoptRecordTable

서버 EAV proxy endpoint를 fetch해 opt-ui DataTable로 렌더합니다. columns 미지정 시 values key를 기준으로 자동 추론합니다.

BrandApp Control Center

SDK verifier, auth health, secret rotation, EAV drift, AI credit guard, webhook replay, terms publication을 묶은 운영 콘솔형 예제입니다.

PreviousOverviewbrandapp-sdk 기능을 opt-ui 위에 조립한 copy-paste Surface 문서 허브Start
Go to Overview
NextCore Conceptsbrandapp-ui copy-paste Surface 모델, consumer ownership, SDK/server/UI 책임 경계Core Concepts