next-js/skills/skills/custom-hook/SKILL.md
Create custom React hooks following the project's conventions for naming, file structure, and barrel exports. Use this skill whenever the user needs to add a reusable hook, create a custom data-fetching hook, encapsulate stateful logic, add a utility hook, or extract repeated logic into a hook. Trigger on: "create hook", "custom hook", "useXxx", "add a hook", "extract into a hook", or when the user describes reusable stateful logic that should be shared across components.
npx skillsauth add spuneiartur/claude-agent-specs custom-hookInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Create custom React hooks following the project's established patterns. The project has 21+ hooks in /hooks/ with a consistent structure.
use-{name}.js (kebab-case, .js extension — not .jsx)/hooks/use-{name}.jsexport default of the hook function (no named exports)// hooks/use-{name}.js
import { useState, useEffect, useCallback } from 'react';
const use{Name} = (initialValue) => {
const [state, setState] = useState(initialValue);
// Hook logic here
return { state, setState }; // Return an object for named destructuring
};
export default use{Name};
Add to hooks/index.js:
export { default as use{Name} } from './use-{name}';
This enables importing via import { use{Name} } from '@hooks';.
Wraps a third-party hook with project-specific defaults and behavior. Examples: useQuery, useMutation, useInfiniteQuery.
// Wraps react-query's useMutation with auto toast + redirect
import { toaster } from '@lib';
import { useRouter } from 'next/router';
import { useQueryClient, useMutation as useQueryMutation } from 'react-query';
const useMutation = (fn, options = {}) => {
const { successCallback, errorCallback, redirectOnSuccess, invalidateQueries, ...rest } = options;
const router = useRouter();
const queryClient = useQueryClient();
return useQueryMutation(fn, {
onSuccess: (data) => {
if (invalidateQueries) queryClient.invalidateQueries(invalidateQueries);
if (data?.message) toaster.success(data.message);
if (redirectOnSuccess) router.push(redirectOnSuccess);
if (typeof successCallback === 'function') successCallback();
},
onError: (err) => {
if (err?.message) toaster.error(err.message);
if (typeof errorCallback === 'function') errorCallback();
},
...rest,
});
};
export default useMutation;
Manages a small, focused piece of UI state. Examples: useDisclosure, useToggle.
// useDisclosure - manages open/close state for modals, dropdowns, etc.
import { useState, useCallback } from 'react';
const useDisclosure = (initial = false) => {
const [isOpen, setIsOpen] = useState(initial);
const show = useCallback(() => setIsOpen(true), []);
const hide = useCallback(() => setIsOpen(false), []);
const toggle = useCallback(() => setIsOpen((prev) => !prev), []);
return { isOpen, show, hide, toggle };
};
export default useDisclosure;
Uses useEffect with cleanup. Examples: useDebounce, useOnClickOutside, useIntersectionObserver.
// useDebounce - debounces a value by delay
import { useState, useEffect } from 'react';
const useDebounce = (value, delay = 300) => {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debouncedValue;
};
export default useDebounce;
Provides utilities for working with data structures. Examples: useArray.
// useArray - array manipulation utilities
import { useState, useCallback } from 'react';
const useArray = (initial = []) => {
const [value, setValue] = useState(initial);
const push = useCallback((item) => setValue((arr) => [...arr, item]), []);
const remove = useCallback((index) => setValue((arr) => arr.filter((_, i) => i !== index)), []);
const clear = useCallback(() => setValue([]), []);
return { value, setValue, push, remove, clear };
};
export default useArray;
const { isOpen, show } = useDisclosure()useCallback to prevent unnecessary re-rendersuseEffectuseArray, useChildren, useCollapsible, useCombobox, useDebounce, useDisclosure, useDropdown, useInfiniteQuery, useIntersectionObserver, useMutation, useObserver, useOnClickOutside, useProfile, useQuery, useRerender, useScrollRestoration, useScrollReveal, useSelect, useSlugGenerator, useSwipeable, useToggletools
Replace with description of the skill and when Claude should use it.
tools
Comprehensive website performance audit and optimization skill. Identifies and automatically fixes performance issues including image optimization, video compression, lazy loading, Core Web Vitals, bundle size, and rendering strategy. Uses Lighthouse (via CLI or MCP when available), ffmpeg for media processing, and the project's existing Image component with blur-up lazy loading. Use this skill whenever the user mentions: website speed, page load time, performance audit, Core Web Vitals, Lighthouse, optimize images, compress videos, lazy loading, LCP, CLS, FID, INP, slow website, speed up, performance optimization, image compression, video optimization, blur placeholder, WebP conversion, media audit, bundle size, or wants to improve their website's loading performance. Also trigger when the user says "my site is slow", "optimize for speed", "reduce load time", "improve performance", or asks about image/video optimization in any context.
tools
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
tools
Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui). Use for complex artifacts requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX artifacts.