Korin UI
Korin UI adalah kumpulan komponen UI untuk aplikasi berbasis AI yang dibangun di atas shadcn/ui dan Tailwind CSS. Paket ini menyediakan shadcn registry jarak jauh sehingga Anda bisa menarik komponen langsung ke aplikasi menggunakan shadcn CLI. Komponen yang tersedia mencakup pengalaman chat lengkap: provider, tampilan chat halaman penuh, tombol chat mengambang, input dengan lampiran file, bubble pesan kaya konten, reasoning, pemilih file, alur unggah, dan lainnya.
Mulai Cepat
Tambahkan semua komponen sekaligus:
npx shadcn@latest add https://ui.korinai.com/all.jsonTambahkan komponen tertentu dengan mengganti all.json menjadi nama file spesifik:
# Contoh komponen tunggal
npx shadcn@latest add https://ui.korinai.com/page-chat.json
npx shadcn@latest add https://ui.korinai.com/chat-input.json
npx shadcn@latest add https://ui.korinai.com/floating-chat.jsonLokasi file hasil instalasi:
- Komponen akan ditempatkan di @/components/korin-ui/*.
- Dependensi ke komponen shadcn akan menggunakan @/components/ui/* milik proyek Anda.
Prasyarat:
- Next.js 14+ (App Router) atau React 18+
- Tailwind CSS dan shadcn/ui sudah dikonfigurasi
- Ikon: lucide-react
Jika Anda menggunakan komponen terkait chat, tambahkan paket berikut:
pnpm add ai lucide-react @korinai/libs
# atau: npm i ai lucide-react @korinai/libsReferensi
Showcase dan registry
Lihat showcase komponen Korin UI beserta entri registry shadcn di:
Anda dapat melihat pratinjau langsung dan menyalin perintah shadcn add dari situs tersebut.
Provider
Sebagian besar komponen tingkat tinggi membutuhkan provider global untuk konfigurasi, autentikasi, dan konteks agen. Bungkus aplikasi Anda dengan KorinProvider.
// app/providers.tsx (Next.js) atau root layout Anda
"use client";
import { KorinProvider } from "@/components/korin-ui/korin-provider";
export function Providers({ children }: { children: React.ReactNode }) {
return (
<KorinProvider
config={{
baseUrl: "https://your.cdn.or.assets.base/url", // untuk logo/gambar
chatApi: "/api/chat", // endpoint chat yang kompatibel dengan Vercel AI SDK
}}
// Opsi A: token statis (untuk pengujian)
// authToken="<JWT atau API token>"
// Opsi B: pengambil token async (disarankan)
getAuthToken={async () => {
// ambil atau hitung token akses untuk API chat Anda
return "<JWT atau API token>";
}}
language="en"
// translations={customTranslations}
>
{children}
</KorinProvider>
);
}Gunakan di root layout
// app/layout.tsx
import { Providers } from "./providers";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}Contoh penggunaan
PageChat — Embed chat di halaman web Anda
PageChat merender antarmuka chat lengkap dengan header, riwayat, daftar pesan, input, lampiran file, dan pemilih agen.
"use client";
import { PageChat } from "@/components/korin-ui/page-chat";
export default function ChatPage() {
return (
<div className="container mx-auto p-4">
<PageChat
title="Chat with KorinAI"
// pengaturan UI opsional
ui={{ showStop: true, showAttach: true, showActions: true }}
// branding opsional
branding={{
logoLightUrl: "/logo/KorinAILogo-Black.svg",
logoDarkUrl: "/logo/KorinAILogo-White.svg",
headerLogoSize: { width: 28, height: 28 },
}}
/>
</div>
);
}FloatingChat — Tombol chat mengambang + jendela overlay
FloatingChat menampilkan tombol mengambang di kanan bawah untuk membuka jendela chat overlay.
"use client";
import { FloatingChat } from "@/components/korin-ui/floating-chat";
export default function FloatingExample() {
return (
<>
{/* Konten halaman Anda... */}
<FloatingChat
title="Chat with KorinAI"
ui={{ showStop: true, showAttach: true }}
branding={{
logoLightUrl: "/logo/KorinAILogo-Black.svg",
logoDarkUrl: "/logo/KorinAILogo-White.svg",
}}
/>
</>
);
}ChatInput — Susun UI Anda sendiri
Gunakan ChatInput jika Anda ingin membangun permukaan chat kustom. Komponen ini mengelola textarea (auto‑resize), lampiran file, pemilihan agen, dan tombol kirim/berhenti.
"use client";
import { useState } from "react";
import { ChatInput } from "@/components/korin-ui/chat-input";
export default function CustomInput() {
const [status, setStatus] = useState<"submitted" | "streaming" | "ready" | "error">("ready");
const [error, setError] = useState<string | null>(null);
async function handleSubmit(text: string) {
try {
setStatus("submitted");
// Panggil API chat Anda di sini, stream respons, dll.
await new Promise((r) => setTimeout(r, 800));
setStatus("ready");
} catch (e: any) {
setError(e?.message || "Gagal mengirim pesan");
setStatus("error");
}
}
return (
<div className="max-w-2xl mx-auto p-4">
<ChatInput
isLoading={status === "submitted"}
status={status}
error={error}
showTemplate={false}
handleSubmit={handleSubmit}
onStop={() => setStatus("ready")}
/>
</div>
);
}ChatBubble (render pesan)
ChatBubble merender bagian‑bagian pesan kaya konten (teks, reasoning, tools, lampiran). Anda bisa menghubungkannya dengan struktur pesan Anda sendiri atau memakai yang disusun PageChat.
import { ChatBubble } from "@/components/korin-ui/chat-bubble";
// ... di dalam komponen
<ChatBubble
message={{ id: "1", role: "assistant", parts: [{ type: "text", text: "Halo!" }] }}
isStreaming={false}
/>Daftar komponen
Semua komponen tersedia di packages/korin-ui/src/. Gunakan perintah berikut untuk memasang satu komponen via shadcn CLI.
| Komponen | Perintah | Deskripsi |
|---|---|---|
| AvatarKorin | npx shadcn@latest add https://ui.korinai.com/avatar-korin.json | Komponen avatar dengan fallback dan gaya khusus Korin. |
| ChatBubble | npx shadcn@latest add https://ui.korinai.com/chat-bubble.json | Merender bagian pesan (teks, reasoning, tools, lampiran) dengan konfirmasi dan status. |
| ChatInput | npx shadcn@latest add https://ui.korinai.com/chat-input.json | Input multiline dengan auto‑resize, lampiran, pemilih agen, dan tombol kirim/berhenti. |
| ChatLimited | npx shadcn@latest add https://ui.korinai.com/chat-limited.json | Komponen peringatan batas kredit. |
| CodeBlock / CodeBlockCopyButton | npx shadcn@latest add https://ui.korinai.com/code-block-with-copy.json | Code block dengan tombol salin. |
| CodeBlock (dasar) | npx shadcn@latest add https://ui.korinai.com/code-block.json | Renderer code block dasar yang dipakai oleh Response dan lainnya. |
| FilePreviewDialog | npx shadcn@latest add https://ui.korinai.com/file-preview-dialog.json | Dialog/overlay untuk pratinjau gambar, video, audio, dan dokumen; mendukung mode pilih. |
| FileSelector | npx shadcn@latest add https://ui.korinai.com/file-selector.json | Pemilih galeri dengan tab (gambar, video, audio, dokumen) + pencarian + unggah. |
| FloatingChat | npx shadcn@latest add https://ui.korinai.com/floating-chat.json | Tombol mengambang + jendela chat overlay (membungkus PageChat). |
| KorinProvider | npx shadcn@latest add https://ui.korinai.com/korin-provider.json | Provider tingkat aplikasi yang menghubungkan KorinAIProvider dan AgentProvider. |
| SimpleMemoizedMarkdown | npx shadcn@latest add https://ui.korinai.com/memoized-markdown.json | Render markdown sederhana yang di‑memo. |
| PageChat | npx shadcn@latest add https://ui.korinai.com/page-chat.json | Permukaan chat penuh dengan header, riwayat, daftar pesan, dan area input. |
| Reasoning (dan komponennya) | npx shadcn@latest add https://ui.korinai.com/reasoning.json | UI “reasoning” yang dapat dibuka/tutup. |
| Response | npx shadcn@latest add https://ui.korinai.com/response.json | Renderer Markdown yang diperketat dengan KaTeX, GFM, ramah streaming. |
| ScrollAreaExtended | npx shadcn@latest add https://ui.korinai.com/scroll-area-extended.json | Pembungkus praktis di atas shadcn ScrollArea. |
| ToolResults | npx shadcn@latest add https://ui.korinai.com/tool-results.json | Renderer hasil alat (web search, knowledge, image generation). |
| TypingLoader | npx shadcn@latest add https://ui.korinai.com/typing-loader.json | Indikator pengetikan/streaming. |
| UploadButton | npx shadcn@latest add https://ui.korinai.com/upload-button.json | Alur unggah file berbasis drawer dengan pratinjau dan progres. |
| UserConfirmation | npx shadcn@latest add https://ui.korinai.com/user-confirmation.json | UI konfirmasi generik untuk aksi alat (mis. git commit/push). |
Catatan:
- Ganti all.json dengan <nama-komponen>.json untuk memasang komponen tertentu saja.
- Jalur keluaran disetel ke @/components/korin-ui/* agar impor rapi, mis. @/components/korin-ui/page-chat.
Endpoint chatApi minimal — Next.js + Vercel AI SDK
Contoh endpoint streaming minimal yang kompatibel dengan PageChat dan Vercel AI SDK.
Instal dependensi:
pnpm add ai @ai-sdk/openai
# atau: npm i ai @ai-sdk/openaiBuat app/api/chat/route.ts:
import { NextRequest } from "next/server";
import { openai } from "@ai-sdk/openai";
import { streamText } from "ai";
export const runtime = "edge"; // disarankan untuk streaming
export async function POST(req: NextRequest) {
// Opsi: baca header auth
const authHeader = req.headers.get("authorization");
// Lakukan validasi bila perlu
const { messages } = await req.json();
const result = await streamText({
model: openai("gpt-4o-mini"),
messages,
});
return result.toAIStreamResponse();
}Variabel environment:
OPENAI_API_KEY=sk-...Atur config.chatApi pada KorinProvider menjadi /api/chat. DefaultChatTransport yang digunakan PageChat akan mengirim pesan (POST) ke endpoint ini dan merender respons streaming.
Resep
Branding
Sebagian besar komponen chat menerima prop branding untuk mengganti logo dan ukurannya:
branding={{
logoLightUrl: "/logo/KorinAILogo-Black.svg",
logoDarkUrl: "/logo/KorinAILogo-White.svg",
logoSize: { width: 50, height: 50 },
headerLogoSize: { width: 28, height: 28 },
showHeaderLogo: true,
}}Permintaan dan autentikasi
KorinProvider meneruskan authToken (string) atau getAuthToken (async) ke transport chat. Implementasikan salah satu (atau keduanya) dan validasikan header Authorization di backend Anda.
Unggah file dan galeri
ChatInput, FileSelector, dan UploadButton terintegrasi dengan hook dari @korinai/libs (mis. useGallery, useGalleryUpload, useUser). Pastikan backend Anda menyediakan endpoint dan autentikasi yang kompatibel.
Troubleshooting
- Token hilang/tidak valid: Pastikan Anda mengisi authToken atau mengimplementasikan getAuthToken. Status 401 biasanya berarti token tidak ada atau kedaluwarsa.
- baseUrl atau chatApi salah: Periksa ulang pengaturan; coba akses URL langsung di browser.
- Error CORS: Konfigurasikan backend agar mengizinkan origin aplikasi Anda. Saat pengembangan, aktifkan CORS yang permisif atau gunakan proxy.
- SWR tidak memperbarui: Panggil mutate() setelah aksi seperti unggah untuk memicu revalidasi data.
- Error tipe/TypeScript: Pastikan TypeScript dan @types/react kompatibel dengan React 18.