Wikibeem을 만든 방법: ClickUp Docs를 전문 문서 사이트로 전환하기
Source: Dev.to
좌절에서 제품 출시까지의 솔로 개발자 여정
ClickUp을 사랑합니다. 우리 팀이 살아가는 곳이며 — 작업, 문서, 위키, 모든 것이 연결됩니다.
하지만 클라이언트와 문서를 공유해야 할 때마다 같은 장벽에 부딪혔습니다:
https://doc.clickup.com/d/2kxuepwx-192
그 추하고 브랜드가 들어간 비전문적인 URL. 클라이언트는 “왜 ClickUp을 쓰나요? 웹사이트에 올릴 수 있나요?” 라고 물었습니다.
나는 몇 시간을 보냈습니다:
- PDF로 내보내기 (포맷 깨짐)
- Notion에 복사‑붙여넣기 (링크 깨짐)
- GitBook으로 재구성 (맥락 손실)
Cloakist와 같은 우회 방법은 ClickUp 페이지를 프록시만 했기 때문에, 클라이언트는 여전히 클릭하며 내부 내용을 볼 수 있었습니다.
문제는 흔합니다
Reddit, ClickUp 포럼, 피드백 보드를 검색했습니다. 혼자가 아니라는 걸 알게 되었죠:
- “prospect와 doc.clickup.com을 공유했어요. 그들은 우리가 내부적으로 ClickUp을 사용한다고 생각하고 포기했어요.” — r/clickup
- “온보딩 섹션을 공유하고 싶어요. 전체 작업 로드맵을 노출하지 않고는 할 수 없어요.” — feedback.clickup.com
- “Docs 내보내기가 임베드가 깨지고, 글머리표가 사라져요. Notion에서 다시 만드는 데 4 시간이 걸려요.” — Reddit의 Agency PM
수백 명이 같은 불만을 가지고 있었습니다: 에이전시, SaaS 팀, 프리랜서 — 모두 같은 문제에 갇혀 있었죠.
Wikibeem 소개
어느 날 밤 나는 생각했다: 내가 이것을 내 자신을 위해 그리고 그들을 위해 해결할 수 있다면 어떨까?
그렇게 Wikibeem이 탄생했다.
기술 스택
| 구성 요소 | 기술 |
|---|---|
| 프론트엔드 / 서버 | Next.js 16 (App Router), React 19, Tailwind CSS 4 |
| 데이터 레이어 | PostgreSQL + Prisma ORM |
| 호스팅 | Vercel (edge functions) |
| 인증 | NextAuth v5 (beta) – credentials + OAuth |
| 결제 | Paddle (handles global taxes) |
| ClickUp 연동 | ClickUp API v3 (OAuth 2.0) |
| HTTP 클라이언트 | Axios |
| 동기화 엔진 | Custom logic for nested pages, wikis, doc hierarchies |
| Markdown ↔ HTML | Marked, Cheerio, Turndown |
| 검색 | Fuse.js (client‑side fuzzy search) |
| SEO | Per‑site & per‑document SEO, auto‑generated sitemaps |
| 도메인 | Vercel SDK (programmatic custom domain setup, automatic SSL) |
| 국제화 | next‑intl (9 languages: EN, FR, DE, ES, PT, IT, RU, AR, ZH) |
Wikibeem 작동 방식 (내부 구조)
┌─────────────────┐ OAuth ┌─────────────────┐
│ ClickUp API │◄──────────────►│ Wikibeem │
│ (Your Docs) │ │ (Next.js) │
└─────────────────┘ └────────┬────────┘
│
┌───────────────────────┼───────────────────────┐
│ │ │
┌─────▼─────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ PostgreSQL │ │ Vercel │ │ Paddle │
│ (Prisma) │ │ (Domains) │ │ (Payments) │
└───────────┘ └─────────────┘ └─────────────┘
데이터 모델
User
└── Workspace (ClickUp connection)
└── Site (your docs website)
├── Documents (synced from ClickUp)
│ └── Children (nested pages)
├── Domain (custom domain)
├── Theme (colors, logo)
└── SEO Settings
Sync 엔진 세부 정보
ClickUp의 API는 다음과 같은 문서를 반환할 수 있습니다:
- 중첩된 페이지
- 자체 구조를 가진 위키
- 다양한 형식(JSON 블록, Markdown, HTML)의 콘텐츠
엔진은 다음을 수행해야 합니다:
- 워크스페이스의 모든 문서를 가져옵니다.
- 페이지와 그 하위 페이지를 재귀적으로 처리합니다.
- 콘텐츠를 깔끔한 HTML로 변환합니다.
- 부모‑자식 관계를 가진 계층 구조를 구축합니다.
- URL용 고유 슬러그를 생성합니다.
- 중복을 만들지 않도록 업데이트를 처리합니다.
루트‑문서 중복 처리
// The fix: Track root doc IDs and filter them out
const rootDocIds = new Set(docs.map(d => d.id))
// When processing pages, skip if it's actually a root doc
if (rootDocIds.has(page.id)) {
continue // This page is a doc, not a child page
}
슬러그 검사 최적화
첫 번째 버전은 각 슬러그마다 데이터베이스를 조회했으며, 100개의 페이지에 대해 100회 이상의 라운드 트립이 발생했습니다.
// In‑memory slug tracking
const existingSlugs = new Set()
// Instead of: await prisma.document.findUnique(...)
// Now:
if (existingSlugs.has(slug)) {
// generate a new slug
}
existingSlugs.add(newSlug) // Track immediately
동기화 시간은 30 초 이상에서 10 초 이하로 감소했습니다.
프로그래매틱 도메인 프로비저닝 (Vercel SDK)
import { Vercel } from '@vercel/sdk'
const vercel = new Vercel({ accessToken: process.env.VERCEL_TOKEN })
// Add domain
await vercel.projects.addProjectDomain({
idOrName: projectId,
requestBody: { name: 'docs.yourcompany.com' }
})
// Get verification records
const config = await vercel.domains.getDomainConfig({
domain: 'docs.yourcompany.com'
})
사용자는 CNAME 레코드를 추가하고 “Verify”를 클릭하면, 문서가 자동으로 HTTPS와 함께 사용자 지정 도메인에서 실시간으로 제공됩니다.
향후 로드맵 (진행 중인 기능)
- ClickUp 웹훅을 통한 실시간 동기화
- 분석 – 사람들이 어떤 문서를 읽는지 확인
- 비밀번호 보호 문서 – 비공개 클라이언트 포털용
- 추가 테마
- API 접근 – 파워 유저용
Get started
Wikibeem은 **wikibeem.com**에서 라이브 중입니다.
- ClickUp 작업 공간을 연결하세요.
- 문서를 동기화하세요.
- 사용자 지정 도메인을 추가하세요.
5분 이내에 전문적인 문서 사이트를 만들 수 있습니다.
Feedback
I’m building this in public and genuinely want your input. What features would make this useful for you? What’s missing?
Reach out on Twitter/X or LinkedIn. Let’s build this together.