Skip to content

React Server Components

13 components in tekivex-ui are RSC-compatible: they use no hooks, no browser APIs, and no event handlers, so they render on the server in Next.js App Router (or any other RSC framework) without "use client".

ComponentNotes
TkxBadgeStatus pill
TkxAvatarUser avatar with initials fallback
TkxDividerHorizontal/vertical separator
TkxTypographyHeadings, paragraphs, captions
TkxSkeletonLoading shimmer placeholder
TkxSpinSpinner / loader
TkxEmptyEmpty-state placeholder
TkxStatisticAnimated numeric KPI
TkxTagInline tag with optional close button
TkxCardCard container + Header/Body/Footer
TkxAlertStatus alert (info/success/warning/danger)
TkxProgressLinear / circular progress
TkxTimelineVertical timeline of events
// app/dashboard/page.tsx — Server Component
import { TkxCard, TkxCardBody, TkxStatistic } from 'tekivex-ui';
export default async function Dashboard() {
const data = await fetch('https://api.example.com/metrics', {
cache: 'no-store',
}).then(r => r.json());
return (
<TkxCard>
<TkxCardBody>
<TkxStatistic title="Active users" value={data.active} />
</TkxCardBody>
</TkxCard>
);
}

No "use client". The HTML ships fully rendered on first byte.

Anything interactive — buttons with onClick, forms with onChange, modals, the image editor, the captcha — must be in a client boundary. The convention is to keep your 'use client' boundaries small and leaf-level:

// app/page.tsx — Server
import { TkxCard, TkxCardBody } from 'tekivex-ui';
import { LoginForm } from './login-form';
export default function Page() {
return (
<TkxCard>
<TkxCardBody>
<LoginForm />
</TkxCardBody>
</TkxCard>
);
}
// app/login-form.tsx — Client island
'use client';
import { TkxInput, TkxButton } from 'tekivex-ui';
// …

The Server Component still ships the Card structure on first byte; only the form hydrates.