Communitygithub.com

ComeOnOliver/skillshub

Next.js 15 애플리케이션을 위한 프론트엔드 개발 가이드라인. React 19, TypeScript, Shadcn/ui, Tailwind CSS를 사용한 모던 패턴. Server Components, Client Components, App Router, 파일 구조, Shadcn/ui 컴포넌트, 성능 최적화, TypeScript 모범 사례 포함. 컴포넌트, 페이지, 기능 생성, 데이터 페칭, 스타일링, 라우팅, 프론트엔드 코드 작업 시 사용.

skillshub 是什麼?

skillshub is a Claude Code agent skill that next.js 15 애플리케이션을 위한 프론트엔드 개발 가이드라인. React 19, TypeScript, Shadcn/ui, Tailwind CSS를 사용한 모던 패턴. Server Components, Client Components, App Router, 파일 구조, Shadcn/ui 컴포넌트, 성능 최적화, TypeScript 모범 사례 포함. 컴포넌트, 페이지, 기능 생성, 데이터 페칭, 스타일링, 라우팅, 프론트엔드 코드 작업 시 사용.

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ComeOnOliver/skillshub/tree/HEAD/skills/aiskillstore/marketplace/0chan-smc/frontend-dev-guidelines

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Frontend Development Guidelines

Purpose

Comprehensive guide for modern Next.js 15 development with React 19, emphasizing Server Components, Client Components, App Router patterns, Shadcn/ui components, proper file organization, and performance optimization.

When to Use This Skill

  • Creating new components or pages
  • Building new features
  • Fetching data (Server Components, Server Actions)
  • Setting up routing with Next.js App Router
  • Styling components with Tailwind CSS and Shadcn/ui
  • Performance optimization
  • Organizing frontend code
  • TypeScript best practices

Quick Start

New Component Checklist

Creating a component? Follow this checklist:

  • Determine Server vs Client Component (default: Server Component)
  • Add "use client" directive only if needed (interactivity, hooks, browser APIs)
  • Use TypeScript with explicit prop types
  • Import Shadcn/ui components from @/components/ui
  • Use Tailwind CSS classes for styling
  • Import aliases: @/components, @/lib, @/hooks
  • Use cn() utility for conditional classes
  • Default export at bottom
  • Use Server Components for data fetching when possible

New Page Checklist

Creating a page? Set up this structure:

  • Create app/{route-name}/page.tsx for route
  • Use Server Component by default
  • Fetch data directly in Server Component
  • Create components/ directory for page-specific components
  • Use loading.tsx for loading states
  • Use error.tsx for error boundaries
  • Export metadata for SEO

Import Aliases Quick Reference

AliasResolves ToExample
@/Project rootimport { cn } from '@/lib/utils'
@/componentscomponents/import { Button } from '@/components/ui/button'
@/liblib/import { cn } from '@/lib/utils'
@/hookshooks/import { useMobile } from '@/hooks/use-mobile'
@/appapp/import { Metadata } from 'next'

Defined in: tsconfig.json paths configuration


Common Imports Cheatsheet

// Next.js
import { Metadata } from 'next'
import { Suspense } from 'react'
import { notFound, redirect } from 'next/navigation'

// React (Client Components only)
;('use client')
import { useState, useCallback, useMemo } from 'react'

// Shadcn/ui Components
import { Button } from '@/components/ui/button'
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
import { Input } from '@/components/ui/input'

// Utilities
import { cn } from '@/lib/utils'

// Hooks (Client Components only)
import { useMobile } from '@/hooks/use-mobile'

// Types
import type { ComponentProps } from 'react'

Topic Guides

🎨 Component Patterns

Server Components vs Client Components:

  • Server Components (default): No "use client", can fetch data directly, smaller bundle
  • Client Components: Add "use client" for interactivity, hooks, browser APIs

Key Concepts:

  • Default to Server Components
  • Only use Client Components when necessary
  • Use Shadcn/ui components (already Client Components)
  • Component structure: Props → Data Fetching → Render → Export

Example Server Component:

// app/features/posts/components/PostList.tsx
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'

interface PostListProps {
  posts: Post[]
}

export function PostList({ posts }: PostListProps) {
  return (
    <div className='grid gap-4'>
      {posts.map((post) => (
        <Card key={post.id}>
          <CardHeader>
            <CardTitle>{post.title}</CardTitle>
          </CardHeader>
          <CardContent>{post.content}</CardContent>
        </Card>
      ))}
    </div>
  )
}

Example Client Component:

// app/features/posts/components/PostForm.tsx
'use client'

import { useState } from 'react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'

export function PostForm() {
  const [title, setTitle] = useState('')

  return (
    <form>
      <Input value={title} onChange={(e) => setTitle(e.target.value)} />
      <Button type='submit'>Submit</Button>
    </form>
  )
}

📊 Data Fetching

PRIMARY PATTERN: Server Components

  • Fetch data directly in Server Components
  • Use async/await in Server Components
  • No need for useEffect or data fetching libraries
  • Automatic request deduplication

Server Actions:

  • Use for mutations (forms, updates)
  • Create app/actions/ directory
  • Mark with "use server" directive

Example Server Component with Data Fetching:

// app/posts/page.tsx
import { PostList } from '@/components/PostList'

async function getPosts() {
  const res = await fetch('https://api.example.com/posts', {
    cache: 'no-store', // or 'force-cache', 'revalidate'
  })
  return res.json()
}

export default async function PostsPage() {
  const posts = await getPosts()

  return <PostList posts={posts} />
}

Example Server Action:

// app/actions/posts.ts
'use server'

export async function createPost(formData: FormData) {
  const title = formData.get('title')
  // ... validation and creation logic
  redirect('/posts')
}

📁 File Organization

App Router Structure:

app/
  (routes)/
    page.tsx          # Route page
    layout.tsx        # Route layout
    loading.tsx       # Loading UI
    error.tsx         # Error UI
  components/         # Shared components
    ui/               # Shadcn/ui components
  features/           # Feature-specific code
    posts/
      components/     # Feature components
      actions/        # Server Actions
      types/          # TypeScript types
lib/
  utils.ts            # Utilities (cn, etc.)
hooks/
  use-mobile.ts       # Custom hooks (Client only)

Feature Organization:

  • app/features/{feature}/: Feature-specific pages/routes
  • components/: Truly reusable components
  • components/ui/: Shadcn/ui components (don't modify directly)

🎨 Styling

Tailwind CSS + Shadcn/ui:

  • Use Tailwind utility classes
  • Use cn() utility for conditional classes
  • Shadcn/ui components use CSS variables for theming
  • Customize theme in app/globals.css

Styling Patterns:

import { cn } from '@/lib/utils'

interface ButtonProps {
  variant?: 'primary' | 'secondary'
  className?: string
}

export function Button({ variant = 'primary', className }: ButtonProps) {
  return (
    <button
      className={cn(
        'rounded-md px-4 py-2',
        variant === 'primary' && 'bg-primary text-primary-foreground',
        variant === 'secondary' && 'bg-secondary text-secondary-foreground',
        className,
      )}
    >
      Click me
    </button>
  )
}

Shadcn/ui Components:

  • Import from @/components/ui/{component-name}
  • Components are already styled and accessible
  • Customize via className prop or CSS variables

🛣️ Routing

Next.js App Router - File-Based:

  • Directory: app/{route-name}/page.tsx
  • Nested routes: app/{parent}/{child}/page.tsx
  • Dynamic routes: app/posts/[id]/page.tsx
  • Route groups: app/(marketing)/about/page.tsx

Example Route:

// app/posts/page.tsx
import { Metadata } from 'next'
import { PostList } from '@/components/PostList'

export const metadata: Metadata = {
  title: 'Posts',
  description: 'List of all posts',
}

export default async function PostsPage() {
  const posts = await getPosts()

  return (
    <div className='container mx-auto py-8'>
      <h1 className='text-3xl font-bold mb-6'>Posts</h1>
      <PostList posts={posts} />
    </div>
  )
}

Dynamic Route:

// app/posts/[id]/page.tsx
interface PostPageProps {
  params: Promise<{ id: string }>
}

export default async function PostPage({ params }: PostPageProps) {
  const { id } = await params
  const post = await getPost(id)

  if (!post) {
    notFound()
  }

  return <PostDetail post={post} />
}

⏳ Loading & Error States

Loading States:

  • Create loading.tsx in route directory
  • Automatically wraps page in Suspense
  • Use for route-level loading

Error Boundaries:

  • Create error.tsx in route directory
  • Automatically catches errors in route
  • Can reset error state

Example Loading UI:

// app/posts/loading.tsx
export default function Loading() {
  return (
    <div className='flex items-center justify-center min-h-screen'>
      <div className='animate-spin rounded-full h-8 w-8 border-b-2 border-primary' />
    </div>
  )
}

Example Error UI:

// app/posts/error.tsx
'use client'

import { useEffect } from 'react'
import { Button } from '@/components/ui/button'

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    console.error(error)
  }, [error])

  return (
    <div className='flex flex-col items-center justify-center min-h-screen'>
      <h2 className='text-2xl font-bold mb-4'>Something went wrong!</h2>
      <Button onClick={reset}>Try again</Button>
    </div>
  )
}

⚡ Performance

Optimization Patterns:

  • Use Server Components (smaller bundle)
  • Use next/image for images
  • Use next/font for fonts
  • Lazy load Client Components when possible
  • Use useMemo and useCallback in Client Components
  • Stream data with Suspense boundaries

Image Optimization:

import Image from 'next/image'

export function Avatar({ src, alt }: { src: string; alt: string }) {
  return (
    <Image
      src={src}
      alt={alt}
      width={40}
      height={40}
      className='rounded-full'
    />
  )
}

Streaming with Suspense:

import { Suspense } from 'react'
import { PostList } from '@/components/PostList'
import { Loading } from '@/components/Loading'

export default function Page() {
  return (
    <div>
      <Suspense fallback={<Loading />}>
        <PostList />
      </Suspense>
    </div>
  )
}

📘 TypeScript

Standards:

  • Strict mode enabled
  • No any type
  • Explicit return types on functions
  • Type imports: import type { Post } from '@/types/post'
  • Component prop interfaces with JSDoc

Example:

import type { ComponentProps } from 'react'
import { Button } from '@/components/ui/button'

/**
 * Custom button component with loading state
 */
interface CustomButtonProps extends ComponentProps<typeof Button> {
  isLoading?: boolean
}

export function CustomButton({
  isLoading,
  children,
  ...props
}: CustomButtonProps) {
  return (
    <Button disabled={isLoading} {...props}>
      {isLoading ? 'Loading...' : children}
    </Button>
  )
}

🔧 Common Patterns

Form Handling:

  • Use Server Actions for form submissions
  • Use react-hook-form with zod for validation (Client Components)
  • Use Shadcn/ui Form components

Example Form with Server Action:

// app/actions/posts.ts
'use server'

import { z } from 'zod'

const createPostSchema = z.object({
  title: z.string().min(1),
  content: z.string().min(1),
})

export async function createPost(formData: FormData) {
  const rawData = {
    title: formData.get('title'),
    content: formData.get('content'),
  }

  const validated = createPostSchema.parse(rawData)
  // ... create post logic
  redirect('/posts')
}

Metadata:

import { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'Posts',
  description: 'List of all posts',
  openGraph: {
    title: 'Posts',
    description: 'List of all posts',
  },
}

Core Principles

  1. Server Components First: Default to Server Components, use Client Components only when needed
  2. App Router Structure: Use file-based routing with app/ directory
  3. Shadcn/ui Components: Use pre-built accessible components
  4. Tailwind CSS: Utility-first styling with cn() helper
  5. TypeScript Strict: No any, explicit types
  6. Performance: Use Server Components, optimize images, lazy load when needed
  7. File Organization: Features in app/features/, shared in components/
  8. Import Aliases: Use @/ prefix for clean imports

Quick Reference: File Structure

app/
  layout.tsx                    # Root layout
  page.tsx                      # Home page
  globals.css                   # Global styles
  (routes)/
    posts/
      page.tsx                  # Posts list page
      [id]/
        page.tsx                # Post detail page
      loading.tsx               # Loading UI
      error.tsx                 # Error UI
  features/
    posts/
      components/
        PostList.tsx            # Feature components
      actions/
        posts.ts                # Server Actions
components/
  ui/                           # Shadcn/ui components
    button.tsx
    card.tsx
lib/
  utils.ts                      # Utilities (cn, etc.)
hooks/
  use-mobile.ts                 # Custom hooks

Modern Component Template (Quick Copy)

Server Component:

// app/components/PostCard.tsx
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
import type { Post } from '@/types/post'

interface PostCardProps {
  post: Post
}

export function PostCard({ post }: PostCardProps) {
  return (
    <Card>
      <CardHeader>
        <CardTitle>{post.title}</CardTitle>
      </CardHeader>
      <CardContent>
        <p>{post.content}</p>
      </CardContent>
    </Card>
  )
}

Client Component:

// app/components/PostForm.tsx
'use client'

import { useState } from 'react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { createPost } from '@/app/actions/posts'
import { cn } from '@/lib/utils'

export function PostForm({ className }: { className?: string }) {
  const [isLoading, setIsLoading] = useState(false)

  async function handleSubmit(formData: FormData) {
    setIsLoading(true)
    await createPost(formData)
    setIsLoading(false)
  }

  return (
    <form action={handleSubmit} className={cn('space-y-4', className)}>
      <Input name='title' placeholder='Post title' required />
      <Input name='content' placeholder='Post content' required />
      <Button type='submit' disabled={isLoading}>
        {isLoading ? 'Creating...' : 'Create Post'}
      </Button>
    </form>
  )
}

Related Skills

  • backend-dev-guidelines: Backend API patterns that frontend consumes

Skill Status: Optimized for Next.js 15 with App Router, Server Components, and Shadcn/ui

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

ComeOnOliver/skillshub

Create stunning, animation-rich HTML presentations from scratch or by converting PowerPoint files. Use when the user wants to build a presentation, convert a PPT/PPTX to web, or create slides for a talk/pitch. Helps non-designers discover their aesthetic through visual exploration rather than abstract choices.

ComeOnOliver/skillshub

Next.js 16+ 和 Turbopack — 增量打包、文件系统缓存、开发速度,以及何时使用 Turbopack 与 webpack。

ComeOnOliver/skillshub

SwiftUI architecture patterns, state management with @Observable, view composition, navigation, performance optimization, and modern iOS/macOS UI best practices.

ComeOnOliver/skillshub

Provides Tamagui patterns for config v4, compiler optimization, styled context, and cross-platform styling. Must use when working with Tamagui projects (tamagui.config.ts, @tamagui imports).

ComeOnOliver/skillshub

Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.

ComeOnOliver/skillshub

Create high-converting, visually distinctive landing pages. Use when building marketing pages, product launches, SaaS homepages, or any single-page conversion-focused website. Guides section-by-section composition with anti-AI-slop principles.

ComeOnOliver/skillshub

Auto-loaded context for Portfolio Buddy 2 development. Use for ANY task involving: React 19 development, TypeScript, portfolio analysis features, metrics calculations, trading strategy comparison, or working with the Portfolio Buddy 2 codebase. Contains tech stack, known issues, and architectural constraints.

ComeOnOliver/skillshub

Next.js development tooling via MCP. Inspect routes, components, build info, and debug Next.js apps. Use when working on Next.js applications, debugging routing, or inspecting app structure. NOT for general React or non-Next.js projects.

ComeOnOliver/skillshub

Implement UI using Shadcn MCP (atoms/theme) and 21st.dev MCP (complex sections). Use when adding buttons, layouts, or generating landing pages.

ComeOnOliver/skillshub

A conceptual skill for building an API client in Next.js that handles JWT tokens

ComeOnOliver/skillshub

Best practices and patterns for Next.js App Router, Server Actions, and Routing in this project.

ComeOnOliver/skillshub

The Design System, Theme, and UX rules for the Physical AI Hub.

ComeOnOliver/skillshub

Comprehensive frontend development skill for building modern, performant web applications using ReactJS, NextJS, TypeScript, Tailwind CSS. Includes component scaffolding, performance optimization, bundle analysis, and UI best practices. Use when developing frontend features, optimizing performance, implementing UI/UX designs, managing state, or reviewing frontend code.

ComeOnOliver/skillshub

Build Next.js 16 applications with correct patterns and distinctive design. Use when creating pages, layouts, dynamic routes, upgrading from Next.js 15, or implementing proxy.ts. Covers breaking changes (async params/searchParams, Turbopack, cacheComponents) and frontend aesthetics. NOT when building non-React or backend-only applications.

ComeOnOliver/skillshub

Next.js 16+ uses App Router with Server Components by default. Client Components are only used when interactivity is needed (hooks, event handlers, browser APIs).

ComeOnOliver/skillshub

All TypeScript types are defined in `frontend/types/index.ts`. Types match backend API response structure and provide type safety across the frontend application.

ComeOnOliver/skillshub

Use when working with Next.js App Router tasks - creating pages in /app/, setting up dynamic routes ([id]/page.tsx), implementing nested layouts/templates (layout.tsx), optimizing Server/Client components, or building ERP role-based pages (admin/teacher/student dashboards). Auto-use for all /app/ directory operations, dynamic routing, and App Router-specific features.

ComeOnOliver/skillshub

Apple-inspired clean, minimal, premium UI design. Use when building modern interfaces requiring exceptional UX, clean aesthetics, or Apple-like polish. Triggers on: clean UI, modern design, Apple style, minimal, premium, user-friendly, UX.

ComeOnOliver/skillshub

Use when creating UI designs to avoid generic "AI slop" aesthetics. Enforces distinctive typography, cohesive color systems, purposeful motion, and atmospheric backgrounds. Critical for landing pages, dashboards, and branded interfaces.

ComeOnOliver/skillshub

Build interfaces that resonate, not just render. This skill enforces bold, intentional

相關技能