Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Frontend Component

ASecurity

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).

416 stars
0 votes
0 copies
1 views
Added 2/8/2026
developmenttypescriptreactnextjsnodenodejsapidatabasefrontendperformance

Works with

cursorcliapi

Security Analysis

A100/100

Scanned 2/12/2026

Install to Claude Code

$npx -y skills add aiskillstore/marketplace --skill frontend-component --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Frontend Component?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Frontend Component
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/aiskillstore-frontend-component/badge)](https://www.skillsdirectory.com/skills/aiskillstore-frontend-component)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: frontend-component
description: 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).
---

# Frontend Component Skill

**Purpose**: Guidance for creating Next.js components following server/client patterns and existing component structures.

## Overview

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).

## Server vs Client Components

### Server Components (Default)

**When to Use**:
- Pages and layouts
- Static content
- Data fetching from API (when possible)
- SEO-optimized content

**Pattern**:
```typescript
// No "use client" directive
import { Metadata } from "next";

export const metadata: Metadata = {
  title: "Page Title",
};

export default function PageComponent() {
  return <div>Static content</div>;
}
```

**Example**: `frontend/app/layout.tsx`, `frontend/app/page.tsx`

### Client Components (When Needed)

**When to Use**:
- Interactive elements (buttons, forms, inputs)
- Event handlers (onClick, onChange, etc.)
- React hooks (useState, useEffect, useRouter, etc.)
- Browser APIs (localStorage, window, document, etc.)
- Real-time updates
- Drag and drop functionality

**Pattern**:
```typescript
"use client"; // MUST be first line

import { useState, useEffect } from "react";
import { useRouter } from "next/navigation";

interface ComponentProps {
  prop1: string;
  prop2?: number;
}

export default function ComponentName({ prop1, prop2 }: ComponentProps) {
  const router = useRouter();
  const [state, setState] = useState("");

  useEffect(() => {
    // Side effects
  }, []);

  return <div>{/* Component JSX */}</div>;
}
```

**Example**: `frontend/components/ProtectedRoute.tsx`, `frontend/app/signup/page.tsx`

## Component Structure Template

```typescript
"use client"; // Only if client component

/**
 * Component Name
 *
 * Brief description of what this component does
 */

import { useState, useEffect } from "react";
import { ComponentType } from "@/types";
import { cn } from "@/lib/utils";

interface ComponentProps {
  prop1: string;
  prop2?: number;
  className?: string;
}

export default function ComponentName({ prop1, prop2, className }: ComponentProps) {
  // State
  const [state, setState] = useState("");

  // Effects
  useEffect(() => {
    // Side effects
  }, []);

  // Handlers
  const handleClick = () => {
    // Handler logic
  };

  // Render
  return (
    <div className={cn("base-classes", className)}>
      {/* Component content */}
    </div>
  );
}
```

## Specific Component Patterns

### 1. ProtectedRoute Pattern

**From**: `frontend/components/ProtectedRoute.tsx`

```typescript
"use client";

import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { isAuthenticated } from "@/lib/auth";
import LoadingSpinner from "./LoadingSpinner";

interface ProtectedRouteProps {
  children: React.ReactNode;
}

export default function ProtectedRoute({ children }: ProtectedRouteProps) {
  const router = useRouter();
  const [isAuthorized, setIsAuthorized] = useState(false);
  const [isChecking, setIsChecking] = useState(true);

  useEffect(() => {
    async function checkAuth() {
      try {
        const authenticated = await isAuthenticated();

        if (!authenticated) {
          const currentPath = window.location.pathname;
          if (currentPath !== "/signin") {
            sessionStorage.setItem("redirectAfterLogin", currentPath);
          }
          router.push("/signin");
        } else {
          setIsAuthorized(true);
        }
      } catch (error) {
        console.error("Auth check failed:", error);
        router.push("/signin");
      } finally {
        setIsChecking(false);
      }
    }

    checkAuth();
  }, [router]);

  if (isChecking) {
    return (
      <div className="min-h-screen flex items-center justify-center">
        <LoadingSpinner size="large" />
      </div>
    );
  }

  if (!isAuthorized) {
    return null;
  }

  return <>{children}</>;
}
```

**Pattern**:
- Check authentication on mount
- Show loading spinner during check
- Store intended destination in sessionStorage
- Redirect to `/signin` if not authenticated
- Only render children if authorized

### 2. LoadingSpinner Pattern

**From**: `frontend/components/LoadingSpinner.tsx`

```typescript
interface LoadingSpinnerProps {
  size?: "small" | "medium" | "large";
  color?: string;
  label?: string;
}

export default function LoadingSpinner({
  size = "medium",
  color = "blue",
  label = "Loading...",
}: LoadingSpinnerProps) {
  const sizeClasses = {
    small: "w-4 h-4 border-2",
    medium: "w-8 h-8 border-3",
    large: "w-12 h-12 border-4",
  };

  const colorClasses = {
    blue: "border-blue-600 border-t-transparent",
    gray: "border-gray-600 border-t-transparent",
    white: "border-white border-t-transparent",
  };

  const spinnerClass = `${sizeClasses[size]} ${
    colorClasses[color as keyof typeof colorClasses] || colorClasses.blue
  } rounded-full animate-spin`;

  return (
    <div
      className="flex items-center justify-center"
      role="status"
      aria-label={label}
      aria-live="polite"
    >
      <div className={spinnerClass}></div>
      <span className="sr-only">{label}</span>
    </div>
  );
}
```

**Pattern**:
- Multiple sizes (small, medium, large)
- Multiple colors (blue, gray, white)
- Accessibility labels (`role="status"`, `aria-label`, `aria-live`)
- Screen reader text with `sr-only` class

### 3. Form Handling Pattern

**From**: `frontend/app/signup/page.tsx`

```typescript
"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { api } from "@/lib/api";
import { isValidEmail, getPasswordStrength } from "@/lib/utils";

export default function SignupPage() {
  const router = useRouter();
  const [formData, setFormData] = useState({
    name: "",
    email: "",
    password: "",
  });
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [isLoading, setIsLoading] = useState(false);
  const [apiError, setApiError] = useState("");

  const validateForm = (): boolean => {
    const newErrors: Record<string, string> = {};

    if (!formData.name.trim()) {
      newErrors.name = "Name is required";
    }

    if (!formData.email.trim()) {
      newErrors.email = "Email is required";
    } else if (!isValidEmail(formData.email)) {
      newErrors.email = "Please enter a valid email address";
    }

    // More validation...

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setApiError("");

    if (!validateForm()) {
      return;
    }

    setIsLoading(true);

    try {
      const response = await api.signup(formData);
      if (response.success) {
        router.push("/dashboard");
      } else {
        setApiError(response.message || "Signup failed");
      }
    } catch (error: any) {
      setApiError(error.message || "An error occurred");
    } finally {
      setIsLoading(false);
    }
  };

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    setFormData((prev) => ({ ...prev, [name]: value }));
    // Clear error for this field when user starts typing
    if (errors[name]) {
      setErrors((prev) => ({ ...prev, [name]: "" }));
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* Form fields */}
    </form>
  );
}
```

**Pattern**:
- Separate state for form data, errors, loading, API errors
- Validation function that returns boolean
- Clear errors on input change
- Loading state during submission
- Try-catch for error handling
- Redirect on success

### 4. ToastNotification Pattern

**From**: `frontend/components/ToastNotification.tsx`

```typescript
"use client";

import { useEffect, useState } from "react";
import { ToastMessage, ToastType } from "@/types";

export function useToast() {
  const [toasts, setToasts] = useState<ToastMessage[]>([]);

  const showToast = (type: ToastType, message: string, duration?: number) => {
    const id = `toast-${Date.now()}-${Math.random()}`;
    const newToast: ToastMessage = {
      id,
      type,
      message,
      duration,
    };
    setToasts((prev) => [...prev, newToast]);
  };

  const dismissToast = (id: string) => {
    setToasts((prev) => prev.filter((toast) => toast.id !== id));
  };

  return {
    toasts,
    showToast,
    dismissToast,
    success: (message: string, duration?: number) => showToast("success", message, duration),
    error: (message: string, duration?: number) => showToast("error", message, duration),
    // ...
  };
}
```

**Pattern**:
- Custom hook for toast management
- Auto-dismiss with duration
- Stack multiple toasts
- Helper methods (success, error, warning, info)

## Tailwind CSS Patterns

### 1. Utility Classes Only

```typescript
<div className="flex items-center justify-center gap-4 p-6 bg-white rounded-lg shadow-md">
```

**Pattern**: Use Tailwind utility classes, no inline styles

### 2. Conditional Classes with `cn()` Utility

```typescript
import { cn } from "@/lib/utils";

<div className={cn(
  "base-classes",
  condition && "conditional-classes",
  className // Allow prop override
)}>
```

**Pattern**: Use `cn()` from `@/lib/utils` for conditional classes

### 3. Dark Mode Support

```typescript
<div className="bg-white dark:bg-gray-800 text-gray-900 dark:text-white">
```

**Pattern**: Use `dark:` prefix for dark mode styles

### 4. Responsive Design

```typescript
<div className="w-full sm:w-1/2 md:w-1/3 lg:w-1/4">
```

**Pattern**: Use breakpoint prefixes (`sm:`, `md:`, `lg:`, `xl:`)

## Accessibility Patterns (WCAG 2.1 AA)

### 1. ARIA Labels

```typescript
<button aria-label="Close dialog">×</button>
<div role="status" aria-live="polite" aria-label="Loading...">
```

**Pattern**: Always provide `aria-label` for icon-only buttons

### 2. Semantic HTML

```typescript
<nav>
  <ul>
    <li><a href="/">Home</a></li>
  </ul>
</nav>
```

**Pattern**: Use semantic HTML elements (`nav`, `main`, `section`, `article`, etc.)

### 3. Keyboard Navigation

```typescript
<button
  onClick={handleClick}
  onKeyDown={(e) => {
    if (e.key === "Enter" || e.key === " ") {
      handleClick();
    }
  }}
>
```

**Pattern**: Ensure keyboard accessibility for all interactive elements

### 4. Screen Reader Text

```typescript
<span className="sr-only">Loading content</span>
```

**Pattern**: Use `sr-only` class for screen reader-only text

### 5. Focus Management

```typescript
<input
  autoFocus
  className="focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
```

**Pattern**: Always provide visible focus indicators

## File Naming Conventions

- **Pages**: kebab-case (e.g., `signup.tsx`, `signin.tsx`)
- **Components**: PascalCase (e.g., `TaskList.tsx`, `TaskItem.tsx`)
- **Layouts**: `layout.tsx`
- **Error Pages**: `error.tsx`, `not-found.tsx`

## Constitution Requirements

- **FR-033**: Next.js 16+ App Router structure ✅
- **FR-034**: Server components default, client when needed ✅
- **FR-035**: Error boundaries ✅
- **FR-036**: WCAG 2.1 AA compliance ✅
- **FR-037**: TypeScript strict mode ✅
- **FR-038**: Prettier formatting ✅
- **FR-039**: ESLint rules ✅

## References

- **Specification**: `specs/002-frontend-todo-app/spec.md` - Component specifications
- **Existing Components**: `frontend/components/*.tsx` - Component examples
- **Existing Pages**: `frontend/app/*.tsx` - Page examples

## Advanced Component Patterns

### 1. Drag and Drop Pattern (Phase 7 - T065)

**Library**: `@dnd-kit/core`

```typescript
"use client";

import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors } from "@dnd-kit/core";
import { SortableContext, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";

export default function SortableTaskList({ tasks, onReorder }: Props) {
  const sensors = useSensors(
    useSensor(PointerSensor),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  );

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event;
    if (over && active.id !== over.id) {
      onReorder(active.id, over.id);
    }
  };

  return (
    <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
      <SortableContext items={tasks.map(t => t.id)} strategy={verticalListSortingStrategy}>
        {tasks.map(task => (
          <SortableTaskItem key={task.id} task={task} />
        ))}
      </SortableContext>
    </DndContext>
  );
}
```

**Pattern**: Use `@dnd-kit/core` for drag and drop, handle reorder on drag end

### 2. Undo/Redo Pattern (Phase 7 - T066)

```typescript
"use client";

import { useReducer } from "react";

interface HistoryState<T> {
  past: T[];
  present: T;
  future: T[];
}

function historyReducer<T>(state: HistoryState<T>, action: { type: string; newPresent?: T }): HistoryState<T> {
  const { past, present, future } = state;

  switch (action.type) {
    case "UNDO":
      if (past.length === 0) return state;
      return {
        past: past.slice(0, past.length - 1),
        present: past[past.length - 1],
        future: [present, ...future],
      };
    case "REDO":
      if (future.length === 0) return state;
      return {
        past: [...past, present],
        present: future[0],
        future: future.slice(1),
      };
    case "SET":
      if (action.newPresent === present) return state;
      return {
        past: [...past, present],
        present: action.newPresent!,
        future: [],
      };
    default:
      return state;
  }
}

export function useHistory<T>(initialPresent: T) {
  const [state, dispatch] = useReducer(historyReducer, {
    past: [],
    present: initialPresent,
    future: [],
  });

  const undo = () => dispatch({ type: "UNDO" });
  const redo = () => dispatch({ type: "REDO" });
  const set = (newPresent: T) => dispatch({ type: "SET", newPresent });

  return { state: state.present, set, undo, redo, canUndo: state.past.length > 0, canRedo: state.future.length > 0 };
}
```

**Pattern**: Use `useReducer` with history pattern for undo/redo functionality

### 3. Real-time Updates with Polling (Phase 7 - T067)

```typescript
"use client";

import { useEffect, useRef } from "react";

export function usePolling(callback: () => Promise<void>, interval: number = 5000) {
  const intervalRef = useRef<NodeJS.Timeout | null>(null);

  useEffect(() => {
    const poll = async () => {
      try {
        await callback();
      } catch (error) {
        console.error("Polling error:", error);
      }
    };

    // Initial call
    poll();

    // Set up polling interval
    intervalRef.current = setInterval(poll, interval);

    // Cleanup
    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
      }
    };
  }, [callback, interval]);
}
```

**Pattern**: Use `setInterval` for polling, cleanup on unmount, handle errors gracefully

### 4. Inline Editing Pattern (Phase 7 - T068)

```typescript
"use client";

import { useState } from "react";

export default function InlineEditable({ value, onSave }: Props) {
  const [isEditing, setIsEditing] = useState(false);
  const [editValue, setEditValue] = useState(value);

  const handleSave = () => {
    onSave(editValue);
    setIsEditing(false);
  };

  const handleCancel = () => {
    setEditValue(value);
    setIsEditing(false);
  };

  if (isEditing) {
    return (
      <input
        value={editValue}
        onChange={(e) => setEditValue(e.target.value)}
        onBlur={handleSave}
        onKeyDown={(e) => {
          if (e.key === "Enter") handleSave();
          if (e.key === "Escape") handleCancel();
        }}
        autoFocus
      />
    );
  }

  return (
    <span onClick={() => setIsEditing(true)} className="cursor-pointer">
      {value}
    </span>
  );
}
```

**Pattern**: Toggle edit mode, save on blur/Enter, cancel on Escape

### 5. Performance Optimization Patterns (Phase 8 - T072)

#### Code Splitting with `next/dynamic`

```typescript
import dynamic from "next/dynamic";

// Lazy load heavy components
const TaskStatistics = dynamic(() => import("@/components/TaskStatistics"), {
  loading: () => <LoadingSpinner />,
  ssr: false, // Disable SSR if not needed
});

const TaskDetailModal = dynamic(() => import("@/components/TaskDetailModal"), {
  loading: () => <LoadingSpinner />,
});
```

**Pattern**: Use `next/dynamic` for code splitting, provide loading fallback

#### Image Optimization

```typescript
import Image from "next/image";

<Image
  src="/image.jpg"
  alt="Description"
  width={500}
  height={300}
  loading="lazy"
  placeholder="blur"
/>
```

**Pattern**: Use Next.js `Image` component for automatic optimization

### 6. Error Boundary Pattern (Phase 8 - T074)

```typescript
"use client";

import React, { Component, ErrorInfo, ReactNode } from "react";

interface Props {
  children: ReactNode;
  fallback?: ReactNode;
}

interface State {
  hasError: boolean;
  error?: Error;
}

export default class ErrorBoundary extends Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error: Error): Partial<State> {
    return { hasError: true, error };
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
    console.error("ErrorBoundary caught an error:", error, errorInfo);
    // Log to error tracking service
  }

  render() {
    if (this.state.hasError) {
      return (
        this.props.fallback || (
          <div className="p-4 bg-red-50 border border-red-200 rounded">
            <h2 className="text-red-800 font-bold">Something went wrong</h2>
            <p className="text-red-600">{this.state.error?.message}</p>
            <button onClick={() => this.setState({ hasError: false })}>Try again</button>
          </div>
        )
      );
    }

    return this.props.children;
  }
}
```

**Pattern**: Class component, catch errors, provide fallback UI, log errors

### 7. PWA Patterns (Phase 8 - T069, T070, T071)

#### Service Worker Setup

```typescript
// public/sw.js or use next-pwa
if ("serviceWorker" in navigator) {
  window.addEventListener("load", () => {
    navigator.serviceWorker
      .register("/sw.js")
      .then((registration) => {
        console.log("SW registered:", registration);
      })
      .catch((error) => {
        console.error("SW registration failed:", error);
      });
  });
}
```

**Pattern**: Register service worker on page load, handle registration errors

#### IndexedDB for Offline Storage

```typescript
import { openDB, DBSchema, IDBPDatabase } from "idb";

interface TaskDB extends DBSchema {
  tasks: {
    key: number;
    value: Task;
    indexes: { "by-user-id": string };
  };
}

export async function getDB(): Promise<IDBPDatabase<TaskDB>> {
  return openDB<TaskDB>("todo-db", 1, {
    upgrade(db) {
      const taskStore = db.createObjectStore("tasks", { keyPath: "id" });
      taskStore.createIndex("by-user-id", "user_id");
    },
  });
}

export async function saveTaskOffline(task: Task) {
  const db = await getDB();
  await db.put("tasks", task);
}

export async function getTasksOffline(userId: string): Promise<Task[]> {
  const db = await getDB();
  return db.getAllFromIndex("tasks", "by-user-id", userId);
}
```

**Pattern**: Use `idb` library for IndexedDB, create stores and indexes, handle offline data

#### Offline Sync Mechanism

```typescript
export async function syncOfflineChanges(userId: string) {
  const db = await getDB();
  const offlineTasks = await db.getAllFromIndex("tasks", "by-user-id", userId);

  for (const task of offlineTasks) {
    if (task.syncStatus === "pending") {
      try {
        await api.createTask(userId, task);
        await db.put("tasks", { ...task, syncStatus: "synced" });
      } catch (error) {
        console.error("Sync failed for task:", task.id, error);
      }
    }
  }
}

// Call on connection restore
window.addEventListener("online", () => {
  syncOfflineChanges(currentUserId);
});
```

**Pattern**: Track sync status, sync on connection restore, handle sync errors

### 8. Caching Strategies (Phase 8 - T073)

```typescript
// Cache API responses
const cache = new Map<string, { data: any; timestamp: number }>();
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes

export async function getCachedData<T>(key: string, fetcher: () => Promise<T>): Promise<T> {
  const cached = cache.get(key);
  if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
    return cached.data;
  }

  const data = await fetcher();
  cache.set(key, { data, timestamp: Date.now() });
  return data;
}
```

**Pattern**: Use Map for in-memory cache, check expiration, update cache on fetch

### 9. Error Logging and Tracking (Phase 8 - T075)

```typescript
export function logError(error: Error, context?: Record<string, any>) {
  console.error("Error:", error, context);

  // Send to error tracking service (e.g., Sentry)
  if (typeof window !== "undefined" && (window as any).Sentry) {
    (window as any).Sentry.captureException(error, {
      extra: context,
    });
  }

  // Or send to custom endpoint
  fetch("/api/log-error", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      message: error.message,
      stack: error.stack,
      context,
      timestamp: new Date().toISOString(),
    }),
  }).catch((err) => console.error("Failed to log error:", err));
}
```

**Pattern**: Log to console, send to error tracking service, include context

## Common Patterns Summary

1. ✅ Use Server Components by default
2. ✅ Add `"use client"` only when needed
3. ✅ Use TypeScript interfaces for props
4. ✅ Use `cn()` utility for conditional classes
5. ✅ Always include accessibility attributes
6. ✅ Use semantic HTML elements
7. ✅ Provide loading states
8. ✅ Handle errors gracefully
9. ✅ Use Tailwind utility classes
10. ✅ Support dark mode with `dark:` prefix
11. ✅ Use `@dnd-kit/core` for drag and drop
12. ✅ Use `useReducer` for undo/redo
13. ✅ Use `setInterval` for polling with cleanup
14. ✅ Use `next/dynamic` for code splitting
15. ✅ Use ErrorBoundary for error handling
16. ✅ Use IndexedDB for offline storage
17. ✅ Sync offline changes on connection restore
18. ✅ Cache API responses with expiration
19. ✅ Log errors to tracking service

Attribution

aiskillstoreaiskillstore
View sourceMore from aiskillstore →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

284722 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2192 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →