بنقرة واحدة
revealui-react-nextjs-patterns
React 19 and Next.js 16 best practices for RevealUI development
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
React 19 and Next.js 16 best practices for RevealUI development
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| title | RevealUI React 19 & Next.js 16 Patterns |
| visibility | internal |
| status | verified |
| audience | agent |
| name | revealui-react-nextjs-patterns |
| description | React 19 and Next.js 16 best practices for RevealUI development |
| version | 0.1.0 |
| author | RevealUI Team |
| tags | ["react","nextjs","patterns","server-components"] |
| compatibility | ["claude-code","universal"] |
| allowedTools | ["Read","Write","Edit","Grep","Glob"] |
Best practices and patterns for React 19 and Next.js 16 development in the RevealUI framework.
Always use Server Components by default unless you need client-side interactivity.
// ✅ GOOD: Server Component (default)
export default async function Page() {
const data = await fetchData()
return <div>{data}</div>
}
// ❌ BAD: Unnecessary "use client"
"use client"
export default function Page() {
return <div>Static content</div>
}
Push "use client" boundaries as low as possible in the component tree.
// ✅ GOOD: Only interactive parts are client components
// app/page.tsx (Server Component)
import { InteractiveButton } from './InteractiveButton'
export default function Page() {
return (
<div>
<h1>Server-rendered heading</h1>
<InteractiveButton /> {/* Client component */}
</div>
)
}
// app/InteractiveButton.tsx
"use client"
export function InteractiveButton() {
return <button onClick={() => alert('Hi')}>Click</button>
}
// ❌ BAD: Hooks in Server Component
export default function Page() {
const [state, setState] = useState(0) // Error!
return <div>{state}</div>
}
// ✅ GOOD: Extract to Client Component
"use client"
export function Counter() {
const [state, setState] = useState(0)
return <button onClick={() => setState(s => s + 1)}>{state}</button>
}
// ✅ GOOD: Async Server Component
export default async function PostPage({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug)
return <article>{post.content}</article>
}
// ❌ BAD: useEffect for data fetching in Client Component
"use client"
export default function PostPage() {
const [post, setPost] = useState(null)
useEffect(() => {
fetchPost().then(setPost)
}, [])
return <article>{post?.content}</article>
}
// ✅ GOOD: Fetch in parallel
export default async function Page() {
const [posts, categories] = await Promise.all([
getPosts(),
getCategories()
])
return <Layout posts={posts} categories={categories} />
}
// ❌ BAD: Sequential fetching
export default async function Page() {
const posts = await getPosts()
const categories = await getCategories() // Waits for posts
return <Layout posts={posts} categories={categories} />
}
// app/posts/loading.tsx
export default function Loading() {
return <PostSkeleton />
}
// app/posts/error.tsx
"use client"
export default function Error({ error, reset }: {
error: Error
reset: () => void
}) {
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={reset}>Try again</button>
</div>
)
}
// ✅ GOOD: Use RevealUI for data fetching
import { getRevealUI } from '@revealui/core'
export default async function PostsPage() {
const revealui = await getRevealUI()
const posts = await revealui.find({
collection: 'posts',
where: { _status: { equals: 'published' } },
})
return <PostsList posts={posts.docs} />
}
// ✅ GOOD: Check permissions in Server Components
import { getCurrentUser } from '@revealui/auth'
export default async function AdminPage() {
const user = await getCurrentUser()
if (!user || user.role !== 'admin') {
redirect('/login')
}
return <AdminDashboard />
}
// ✅ GOOD: Use generateMetadata for SEO
import type { Metadata } from 'next'
export async function generateMetadata({
params
}: {
params: { slug: string }
}): Promise<Metadata> {
const post = await getPost(params.slug)
return {
title: post.title,
description: post.meta?.description,
openGraph: {
images: [post.meta?.image?.url],
},
}
}
import Image from 'next/image'
// ✅ GOOD: Use Next.js Image component
<Image
src={media.url}
alt={media.alt}
width={media.width}
height={media.height}
priority={isAboveFold}
/>
// ❌ BAD: Regular img tag
<img src={media.url} alt={media.alt} />
import dynamic from 'next/dynamic'
// ✅ GOOD: Code split large client components
const RichTextEditor = dynamic(
() => import('@/components/RichTextEditor'),
{ ssr: false, loading: () => <EditorSkeleton /> }
)
import { Suspense } from 'react'
// ✅ GOOD: Stream slow components
export default function Page() {
return (
<div>
<FastContent />
<Suspense fallback={<Skeleton />}>
<SlowContent />
</Suspense>
</div>
)
}
// app/actions.ts
"use server"
export async function createPost(formData: FormData) {
const title = formData.get('title')
const revealui = await getRevealUI()
return await revealui.create({
collection: 'posts',
data: { title },
})
}
// app/new-post/page.tsx
import { createPost } from '../actions'
export default function NewPost() {
return (
<form action={createPost}>
<input name="title" required />
<button type="submit">Create</button>
</form>
)
}
"use client"
import { useActionState } from 'react'
import { useFormStatus } from 'react-dom'
function SubmitButton() {
const { pending } = useFormStatus()
return (
<button type="submit" disabled={pending}>
{pending ? 'Submitting...' : 'Submit'}
</button>
)
}
export function PostForm() {
const [state, formAction] = useActionState(createPost, null)
return (
<form action={formAction}>
<input name="title" />
<SubmitButton />
{state?.error && <p>{state.error}</p>}
</form>
)
}
anyServer Component: Default, can be async, no hooks, server-only code OK Client Component: "use client", hooks allowed, runs in browser, interactive
When to use Client Components:
When to use Server Components:
Look at these files for good examples:
apps/admin/src/app/(frontend)/posts/[slug]/page.tsx - Async Server Componentapps/admin/src/lib/components/RichText/serialize.tsx - Server-side renderingapps/admin/src/lib/blocks/Form/Component.tsx - Client Component with hooksapps/admin/src/lib/globals/Header/Component.client.tsx - Interactive headerAlways follow these patterns to maintain consistency and performance in RevealUI!
RevealUI coding conventions for any code task — writing, editing, reviewing, creating, fixing, refactoring, changing, adding, or updating TypeScript, React, CSS, or config files. Covers TypeScript strict mode, ES Modules, Biome formatting, Tailwind v4 syntax, conventional commits, monorepo workspace protocol, feature gating, parameterization, and unused declaration policy.
RevealUI database conventions for any task involving database, schema, query, migration, Drizzle ORM, Neon, PostgreSQL, pgvector, vectors, embeddings, or data modeling. Covers the single Neon-primary database and its pgvector tables.
Systematic debugging workflow for RevealUI. Use when encountering any bug, test failure, unexpected behavior, error, or broken functionality. Prevents shotgun debugging.
RevealUI deployment guide — Vercel configuration, GitHub Actions deploy workflow, secret management, domain aliasing, and troubleshooting. Invoke when working on deploy.yml, vercel.json, deployment secrets, domain configuration, or debugging deploy failures.
Code review checklist for RevealUI. Use when reviewing code, completing a feature, checking quality, or before committing. Invoke explicitly with $revealui-review.
RevealUI safety guardrails for any code task — editing, writing, creating, fixing, refactoring, changing, adding, updating, or removing files. Protects credentials, enforces import boundaries, ensures code quality, and verifies work before completion.