一键导入
nextjs-data-access
This skill should be used when fetching data, setting up SWR, or implementing data fetching patterns. Guides data access patterns for Next.js.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
This skill should be used when fetching data, setting up SWR, or implementing data fetching patterns. Guides data access patterns for Next.js.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
This skill should be used when implementing code, creating files, or writing new features. Provides complete file structure, naming patterns, and import rules.
Decompose large requirements into phased task files that fit AI context windows using Gherkin + State Machine approach.
This skill should be used when working with database, Drizzle ORM, entities, schemas, migrations, and seeds. It provides Rails-style DB conventions, local sqlite/libSQL file defaults, and Effect-friendly data patterns.
Use this skill when generating enterprise admin, back-office, or operations module UI. Activates on: new module screen, admin panel, dashboard, operations list, approval queue, entity detail, multi-step form wizard, RBAC console, audit log, analytics cockpit, support console, settings page, or any layout described as "enterprise", "compact", or "admin-heavy". Provides recipe selection, page anatomy contract, density mode, state checklist, and AI prompt template.
This skill should be used when performing browser testing, verifying in browser, or runtime checks. Guides browser verification patterns.
This skill should be used when working with Chakra UI, UI components, or the design system. Guides Chakra UI v3 and Ark UI patterns.
| name | nextjs-data-access |
| description | This skill should be used when fetching data, setting up SWR, or implementing data fetching patterns. Guides data access patterns for Next.js. |
Use this skill when implementing data fetching, caching, or data access patterns.
// src/modules/users/screens/UserListScreen.tsx
import { db } from '@/shared/lib/db';
export async function UserListScreen() {
// Direct database access in Server Components
const users = await db.user.findMany({
orderBy: { createdAt: 'desc' },
});
return <UserList users={users} />;
}
import { unstable_cache } from 'next/cache';
import { db } from '@/shared/lib/db';
const getUsers = unstable_cache(
async () => {
return db.user.findMany();
},
['users'],
{
revalidate: 60, // 60 seconds
tags: ['users'],
}
);
export async function UserListScreen() {
const users = await getUsers();
return <UserList users={users} />;
}
// src/modules/products/lib/api.ts
export async function fetchProducts() {
const res = await fetch('https://api.example.com/products', {
next: {
revalidate: 3600, // Cache for 1 hour
tags: ['products'],
},
});
if (!res.ok) {
throw new Error('Failed to fetch products');
}
return res.json();
}
// Usage in Server Component
export async function ProductListScreen() {
const products = await fetchProducts();
return <ProductList products={products} />;
}
// src/shared/lib/fetcher.ts
export const fetcher = async (url: string) => {
const res = await fetch(url);
if (!res.ok) {
const error = new Error('An error occurred while fetching');
error.info = await res.json();
error.status = res.status;
throw error;
}
return res.json();
};
// src/modules/users/hooks/useUsers.ts
'use client';
import useSWR from 'swr';
import { fetcher } from '@/shared/lib/fetcher';
export function useUsers() {
const { data, error, isLoading, mutate } = useSWR(
'/api/users',
fetcher,
{
revalidateOnFocus: false,
dedupingInterval: 60000,
}
);
return {
users: data,
isLoading,
isError: error,
mutate,
};
}
'use client';
import useSWR from 'swr';
import { updateUser } from '../actions/updateUser';
export function useUser(id: string) {
const { data, mutate } = useSWR(`/api/users/${id}`, fetcher);
const update = async (updates: Partial<User>) => {
// Optimistic update
mutate({ ...data, ...updates }, false);
try {
const result = await updateUser({ id, ...updates });
mutate(result.user);
} catch (error) {
// Revert on error
mutate(data);
throw error;
}
};
return { user: data, update };
}
// src/shared/providers/SWRProvider.tsx
'use client';
import { SWRConfig } from 'swr';
import { fetcher } from '@/shared/lib/fetcher';
export function SWRProvider({ children }: { children: React.ReactNode }) {
return (
<SWRConfig
value={{
fetcher,
revalidateOnFocus: false,
shouldRetryOnError: false,
}}
>
{children}
</SWRConfig>
);
}
// Screen fetches initial data
export async function UserListScreen() {
const initialUsers = await fetchUsers();
return <UserListContainer initialUsers={initialUsers} />;
}
// Container handles client-side updates
'use client';
export function UserListContainer({ initialUsers }) {
const { data: users } = useSWR('/api/users', fetcher, {
fallbackData: initialUsers,
});
return <UserList users={users} />;
}
export async function DashboardScreen() {
// Parallel fetching for better performance
const [users, posts, stats] = await Promise.all([
fetchUsers(),
fetchPosts(),
fetchStats(),
]);
return (
<Dashboard
users={users}
posts={posts}
stats={stats}
/>
);
}
// For data that rarely changes
export const dynamic = 'force-static';
export async function StaticPage() {
const data = await fetchStaticContent();
return <Content data={data} />;
}
// For user-specific or frequently changing data
export const dynamic = 'force-dynamic';
export async function DynamicPage() {
const data = await fetchDynamicContent();
return <Content data={data} />;
}
export const revalidate = 60; // Revalidate every 60 seconds
export async function TimedPage() {
const data = await fetchContent();
return <Content data={data} />;
}
// In a Server Action
import { revalidateTag, revalidatePath } from 'next/cache';
export async function updateProduct(data) {
await db.product.update(data);
// Revalidate specific tag
revalidateTag('products');
// Or revalidate specific path
revalidatePath('/products');
}
// src/app/[locale]/users/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>
);
}
// src/app/[locale]/users/loading.tsx
export default function Loading() {
return <UserListSkeleton />;
}
useEffect for initial data fetching — use Server Components