@0xsown/vibe-code-fe 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.js +181 -0
- package/package.json +32 -0
- package/skills/claude-md-improver/SKILL.md +179 -0
- package/skills/claude-md-improver/references/quality-criteria.md +109 -0
- package/skills/claude-md-improver/references/templates.md +253 -0
- package/skills/claude-md-improver/references/update-guidelines.md +150 -0
- package/skills/find-skills/SKILL.md +133 -0
- package/skills/frontend-design/LICENSE.txt +177 -0
- package/skills/frontend-design/SKILL.md +42 -0
- package/skills/next-best-practices/SKILL.md +153 -0
- package/skills/next-best-practices/async-patterns.md +87 -0
- package/skills/next-best-practices/bundling.md +180 -0
- package/skills/next-best-practices/data-patterns.md +297 -0
- package/skills/next-best-practices/debug-tricks.md +105 -0
- package/skills/next-best-practices/directives.md +73 -0
- package/skills/next-best-practices/error-handling.md +227 -0
- package/skills/next-best-practices/file-conventions.md +140 -0
- package/skills/next-best-practices/font.md +245 -0
- package/skills/next-best-practices/functions.md +108 -0
- package/skills/next-best-practices/hydration-error.md +91 -0
- package/skills/next-best-practices/image.md +173 -0
- package/skills/next-best-practices/metadata.md +301 -0
- package/skills/next-best-practices/parallel-routes.md +287 -0
- package/skills/next-best-practices/route-handlers.md +146 -0
- package/skills/next-best-practices/rsc-boundaries.md +159 -0
- package/skills/next-best-practices/runtime-selection.md +39 -0
- package/skills/next-best-practices/scripts.md +141 -0
- package/skills/next-best-practices/self-hosting.md +371 -0
- package/skills/next-best-practices/suspense-boundaries.md +67 -0
- package/skills/next-cache-components/SKILL.md +411 -0
- package/skills/shadcn-ui/README.md +248 -0
- package/skills/shadcn-ui/SKILL.md +326 -0
- package/skills/shadcn-ui/examples/auth-layout.tsx +177 -0
- package/skills/shadcn-ui/examples/data-table.tsx +313 -0
- package/skills/shadcn-ui/examples/form-pattern.tsx +177 -0
- package/skills/shadcn-ui/resources/component-catalog.md +481 -0
- package/skills/shadcn-ui/resources/customization-guide.md +516 -0
- package/skills/shadcn-ui/resources/migration-guide.md +463 -0
- package/skills/shadcn-ui/resources/setup-guide.md +412 -0
- package/skills/shadcn-ui/scripts/verify-setup.sh +134 -0
- package/skills/supabase-postgres-best-practices/AGENTS.md +68 -0
- package/skills/supabase-postgres-best-practices/CLAUDE.md +68 -0
- package/skills/supabase-postgres-best-practices/README.md +116 -0
- package/skills/supabase-postgres-best-practices/SKILL.md +64 -0
- package/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
- package/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
- package/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
- package/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
- package/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
- package/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
- package/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
- package/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
- package/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
- package/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
- package/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
- package/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
- package/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
- package/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
- package/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
- package/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
- package/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
- package/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
- package/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
- package/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
- package/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
- package/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
- package/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
- package/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
- package/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
- package/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
- package/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
- package/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
- package/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
- package/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
- package/skills/supabase-postgres-best-practices/references/security-rls-performance.md +57 -0
- package/skills/tailwind-design-system/SKILL.md +874 -0
- package/skills/vercel-composition-patterns/AGENTS.md +946 -0
- package/skills/vercel-composition-patterns/README.md +60 -0
- package/skills/vercel-composition-patterns/SKILL.md +89 -0
- package/skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
- package/skills/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
- package/skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
- package/skills/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
- package/skills/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/skills/vercel-composition-patterns/rules/state-context-interface.md +191 -0
- package/skills/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
- package/skills/vercel-composition-patterns/rules/state-lift-state.md +125 -0
- package/skills/vercel-react-best-practices/AGENTS.md +2934 -0
- package/skills/vercel-react-best-practices/README.md +123 -0
- package/skills/vercel-react-best-practices/SKILL.md +136 -0
- package/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
- package/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
- package/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
- package/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
- package/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
- package/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
- package/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
- package/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
- package/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
- package/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
- package/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
- package/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
- package/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
- package/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
- package/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
- package/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
- package/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
- package/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
- package/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
- package/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
- package/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
- package/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
- package/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
- package/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
- package/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
- package/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
- package/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
- package/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
- package/skills/vercel-react-native-skills/AGENTS.md +2897 -0
- package/skills/vercel-react-native-skills/README.md +165 -0
- package/skills/vercel-react-native-skills/SKILL.md +121 -0
- package/skills/vercel-react-native-skills/rules/animation-derived-value.md +53 -0
- package/skills/vercel-react-native-skills/rules/animation-gesture-detector-press.md +95 -0
- package/skills/vercel-react-native-skills/rules/animation-gpu-properties.md +65 -0
- package/skills/vercel-react-native-skills/rules/design-system-compound-components.md +66 -0
- package/skills/vercel-react-native-skills/rules/fonts-config-plugin.md +71 -0
- package/skills/vercel-react-native-skills/rules/imports-design-system-folder.md +68 -0
- package/skills/vercel-react-native-skills/rules/js-hoist-intl.md +61 -0
- package/skills/vercel-react-native-skills/rules/list-performance-callbacks.md +44 -0
- package/skills/vercel-react-native-skills/rules/list-performance-function-references.md +132 -0
- package/skills/vercel-react-native-skills/rules/list-performance-images.md +53 -0
- package/skills/vercel-react-native-skills/rules/list-performance-inline-objects.md +97 -0
- package/skills/vercel-react-native-skills/rules/list-performance-item-expensive.md +94 -0
- package/skills/vercel-react-native-skills/rules/list-performance-item-memo.md +82 -0
- package/skills/vercel-react-native-skills/rules/list-performance-item-types.md +104 -0
- package/skills/vercel-react-native-skills/rules/list-performance-virtualize.md +67 -0
- package/skills/vercel-react-native-skills/rules/monorepo-native-deps-in-app.md +46 -0
- package/skills/vercel-react-native-skills/rules/monorepo-single-dependency-versions.md +63 -0
- package/skills/vercel-react-native-skills/rules/navigation-native-navigators.md +188 -0
- package/skills/vercel-react-native-skills/rules/react-compiler-destructure-functions.md +50 -0
- package/skills/vercel-react-native-skills/rules/react-compiler-reanimated-shared-values.md +48 -0
- package/skills/vercel-react-native-skills/rules/react-state-dispatcher.md +91 -0
- package/skills/vercel-react-native-skills/rules/react-state-fallback.md +56 -0
- package/skills/vercel-react-native-skills/rules/react-state-minimize.md +65 -0
- package/skills/vercel-react-native-skills/rules/rendering-no-falsy-and.md +74 -0
- package/skills/vercel-react-native-skills/rules/rendering-text-in-text-component.md +36 -0
- package/skills/vercel-react-native-skills/rules/scroll-position-no-state.md +82 -0
- package/skills/vercel-react-native-skills/rules/state-ground-truth.md +80 -0
- package/skills/vercel-react-native-skills/rules/ui-expo-image.md +66 -0
- package/skills/vercel-react-native-skills/rules/ui-image-gallery.md +104 -0
- package/skills/vercel-react-native-skills/rules/ui-measure-views.md +78 -0
- package/skills/vercel-react-native-skills/rules/ui-menus.md +174 -0
- package/skills/vercel-react-native-skills/rules/ui-native-modals.md +77 -0
- package/skills/vercel-react-native-skills/rules/ui-pressable.md +61 -0
- package/skills/vercel-react-native-skills/rules/ui-safe-area-scroll.md +65 -0
- package/skills/vercel-react-native-skills/rules/ui-scrollview-content-inset.md +45 -0
- package/skills/vercel-react-native-skills/rules/ui-styling.md +87 -0
- package/skills/web-design-guidelines/SKILL.md +39 -0
- package/templates/AGENTS.md +31 -0
- package/templates/CLAUDE.md +31 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# File Conventions
|
|
2
|
+
|
|
3
|
+
Next.js App Router uses file-based routing with special file conventions.
|
|
4
|
+
|
|
5
|
+
## Project Structure
|
|
6
|
+
|
|
7
|
+
Reference: https://nextjs.org/docs/app/getting-started/project-structure
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
app/
|
|
11
|
+
├── layout.tsx # Root layout (required)
|
|
12
|
+
├── page.tsx # Home page (/)
|
|
13
|
+
├── loading.tsx # Loading UI
|
|
14
|
+
├── error.tsx # Error UI
|
|
15
|
+
├── not-found.tsx # 404 UI
|
|
16
|
+
├── global-error.tsx # Global error UI
|
|
17
|
+
├── route.ts # API endpoint
|
|
18
|
+
├── template.tsx # Re-rendered layout
|
|
19
|
+
├── default.tsx # Parallel route fallback
|
|
20
|
+
├── blog/
|
|
21
|
+
│ ├── page.tsx # /blog
|
|
22
|
+
│ └── [slug]/
|
|
23
|
+
│ └── page.tsx # /blog/:slug
|
|
24
|
+
└── (group)/ # Route group (no URL impact)
|
|
25
|
+
└── page.tsx
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Special Files
|
|
29
|
+
|
|
30
|
+
| File | Purpose |
|
|
31
|
+
|------|---------|
|
|
32
|
+
| `page.tsx` | UI for a route segment |
|
|
33
|
+
| `layout.tsx` | Shared UI for segment and children |
|
|
34
|
+
| `loading.tsx` | Loading UI (Suspense boundary) |
|
|
35
|
+
| `error.tsx` | Error UI (Error boundary) |
|
|
36
|
+
| `not-found.tsx` | 404 UI |
|
|
37
|
+
| `route.ts` | API endpoint |
|
|
38
|
+
| `template.tsx` | Like layout but re-renders on navigation |
|
|
39
|
+
| `default.tsx` | Fallback for parallel routes |
|
|
40
|
+
|
|
41
|
+
## Route Segments
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
app/
|
|
45
|
+
├── blog/ # Static segment: /blog
|
|
46
|
+
├── [slug]/ # Dynamic segment: /:slug
|
|
47
|
+
├── [...slug]/ # Catch-all: /a/b/c
|
|
48
|
+
├── [[...slug]]/ # Optional catch-all: / or /a/b/c
|
|
49
|
+
└── (marketing)/ # Route group (ignored in URL)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Parallel Routes
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
app/
|
|
56
|
+
├── @analytics/
|
|
57
|
+
│ └── page.tsx
|
|
58
|
+
├── @sidebar/
|
|
59
|
+
│ └── page.tsx
|
|
60
|
+
└── layout.tsx # Receives { analytics, sidebar } as props
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Intercepting Routes
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
app/
|
|
67
|
+
├── feed/
|
|
68
|
+
│ └── page.tsx
|
|
69
|
+
├── @modal/
|
|
70
|
+
│ └── (.)photo/[id]/ # Intercepts /photo/[id] from /feed
|
|
71
|
+
│ └── page.tsx
|
|
72
|
+
└── photo/[id]/
|
|
73
|
+
└── page.tsx
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Conventions:
|
|
77
|
+
- `(.)` - same level
|
|
78
|
+
- `(..)` - one level up
|
|
79
|
+
- `(..)(..)` - two levels up
|
|
80
|
+
- `(...)` - from root
|
|
81
|
+
|
|
82
|
+
## Private Folders
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
app/
|
|
86
|
+
├── _components/ # Private folder (not a route)
|
|
87
|
+
│ └── Button.tsx
|
|
88
|
+
└── page.tsx
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Prefix with `_` to exclude from routing.
|
|
92
|
+
|
|
93
|
+
## Middleware / Proxy
|
|
94
|
+
|
|
95
|
+
### Next.js 14-15: `middleware.ts`
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
// middleware.ts (root of project)
|
|
99
|
+
import { NextResponse } from 'next/server';
|
|
100
|
+
import type { NextRequest } from 'next/server';
|
|
101
|
+
|
|
102
|
+
export function middleware(request: NextRequest) {
|
|
103
|
+
// Auth, redirects, rewrites, etc.
|
|
104
|
+
return NextResponse.next();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export const config = {
|
|
108
|
+
matcher: ['/dashboard/:path*', '/api/:path*'],
|
|
109
|
+
};
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Next.js 16+: `proxy.ts`
|
|
113
|
+
|
|
114
|
+
Renamed for clarity - same capabilities, different names:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
// proxy.ts (root of project)
|
|
118
|
+
import { NextResponse } from 'next/server';
|
|
119
|
+
import type { NextRequest } from 'next/server';
|
|
120
|
+
|
|
121
|
+
export function proxy(request: NextRequest) {
|
|
122
|
+
// Same logic as middleware
|
|
123
|
+
return NextResponse.next();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export const proxyConfig = {
|
|
127
|
+
matcher: ['/dashboard/:path*', '/api/:path*'],
|
|
128
|
+
};
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
| Version | File | Export | Config |
|
|
132
|
+
|---------|------|--------|--------|
|
|
133
|
+
| v14-15 | `middleware.ts` | `middleware()` | `config` |
|
|
134
|
+
| v16+ | `proxy.ts` | `proxy()` | `proxyConfig` |
|
|
135
|
+
|
|
136
|
+
**Migration**: Run `npx @next/codemod@latest upgrade` to auto-rename.
|
|
137
|
+
|
|
138
|
+
## File Conventions Reference
|
|
139
|
+
|
|
140
|
+
Reference: https://nextjs.org/docs/app/api-reference/file-conventions
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# Font Optimization
|
|
2
|
+
|
|
3
|
+
Use `next/font` for automatic font optimization with zero layout shift.
|
|
4
|
+
|
|
5
|
+
## Google Fonts
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
// app/layout.tsx
|
|
9
|
+
import { Inter } from 'next/font/google'
|
|
10
|
+
|
|
11
|
+
const inter = Inter({ subsets: ['latin'] })
|
|
12
|
+
|
|
13
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
14
|
+
return (
|
|
15
|
+
<html lang="en" className={inter.className}>
|
|
16
|
+
<body>{children}</body>
|
|
17
|
+
</html>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Multiple Fonts
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import { Inter, Roboto_Mono } from 'next/font/google'
|
|
26
|
+
|
|
27
|
+
const inter = Inter({
|
|
28
|
+
subsets: ['latin'],
|
|
29
|
+
variable: '--font-inter',
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const robotoMono = Roboto_Mono({
|
|
33
|
+
subsets: ['latin'],
|
|
34
|
+
variable: '--font-roboto-mono',
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
38
|
+
return (
|
|
39
|
+
<html lang="en" className={`${inter.variable} ${robotoMono.variable}`}>
|
|
40
|
+
<body>{children}</body>
|
|
41
|
+
</html>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Use in CSS:
|
|
47
|
+
```css
|
|
48
|
+
body {
|
|
49
|
+
font-family: var(--font-inter);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
code {
|
|
53
|
+
font-family: var(--font-roboto-mono);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Font Weights and Styles
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
// Single weight
|
|
61
|
+
const inter = Inter({
|
|
62
|
+
subsets: ['latin'],
|
|
63
|
+
weight: '400',
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
// Multiple weights
|
|
67
|
+
const inter = Inter({
|
|
68
|
+
subsets: ['latin'],
|
|
69
|
+
weight: ['400', '500', '700'],
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
// Variable font (recommended) - includes all weights
|
|
73
|
+
const inter = Inter({
|
|
74
|
+
subsets: ['latin'],
|
|
75
|
+
// No weight needed - variable fonts support all weights
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
// With italic
|
|
79
|
+
const inter = Inter({
|
|
80
|
+
subsets: ['latin'],
|
|
81
|
+
style: ['normal', 'italic'],
|
|
82
|
+
})
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Local Fonts
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import localFont from 'next/font/local'
|
|
89
|
+
|
|
90
|
+
const myFont = localFont({
|
|
91
|
+
src: './fonts/MyFont.woff2',
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
// Multiple files for different weights
|
|
95
|
+
const myFont = localFont({
|
|
96
|
+
src: [
|
|
97
|
+
{
|
|
98
|
+
path: './fonts/MyFont-Regular.woff2',
|
|
99
|
+
weight: '400',
|
|
100
|
+
style: 'normal',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
path: './fonts/MyFont-Bold.woff2',
|
|
104
|
+
weight: '700',
|
|
105
|
+
style: 'normal',
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
// Variable font
|
|
111
|
+
const myFont = localFont({
|
|
112
|
+
src: './fonts/MyFont-Variable.woff2',
|
|
113
|
+
variable: '--font-my-font',
|
|
114
|
+
})
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Tailwind CSS Integration
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
// app/layout.tsx
|
|
121
|
+
import { Inter } from 'next/font/google'
|
|
122
|
+
|
|
123
|
+
const inter = Inter({
|
|
124
|
+
subsets: ['latin'],
|
|
125
|
+
variable: '--font-inter',
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
export default function RootLayout({ children }) {
|
|
129
|
+
return (
|
|
130
|
+
<html lang="en" className={inter.variable}>
|
|
131
|
+
<body>{children}</body>
|
|
132
|
+
</html>
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
// tailwind.config.js
|
|
139
|
+
module.exports = {
|
|
140
|
+
theme: {
|
|
141
|
+
extend: {
|
|
142
|
+
fontFamily: {
|
|
143
|
+
sans: ['var(--font-inter)'],
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Preloading Subsets
|
|
151
|
+
|
|
152
|
+
Only load needed character subsets:
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
// Latin only (most common)
|
|
156
|
+
const inter = Inter({ subsets: ['latin'] })
|
|
157
|
+
|
|
158
|
+
// Multiple subsets
|
|
159
|
+
const inter = Inter({ subsets: ['latin', 'latin-ext', 'cyrillic'] })
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Display Strategy
|
|
163
|
+
|
|
164
|
+
Control font loading behavior:
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
const inter = Inter({
|
|
168
|
+
subsets: ['latin'],
|
|
169
|
+
display: 'swap', // Default - shows fallback, swaps when loaded
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
// Options:
|
|
173
|
+
// 'auto' - browser decides
|
|
174
|
+
// 'block' - short block period, then swap
|
|
175
|
+
// 'swap' - immediate fallback, swap when ready (recommended)
|
|
176
|
+
// 'fallback' - short block, short swap, then fallback
|
|
177
|
+
// 'optional' - short block, no swap (use if font is optional)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Don't Use Manual Font Links
|
|
181
|
+
|
|
182
|
+
Always use `next/font` instead of `<link>` tags for Google Fonts.
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
// Bad: Manual link tag (blocks rendering, no optimization)
|
|
186
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter" rel="stylesheet" />
|
|
187
|
+
|
|
188
|
+
// Bad: Missing display and preconnect
|
|
189
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter" rel="stylesheet" />
|
|
190
|
+
|
|
191
|
+
// Good: Use next/font (self-hosted, zero layout shift)
|
|
192
|
+
import { Inter } from 'next/font/google'
|
|
193
|
+
|
|
194
|
+
const inter = Inter({ subsets: ['latin'] })
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Common Mistakes
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
// Bad: Importing font in every component
|
|
201
|
+
// components/Button.tsx
|
|
202
|
+
import { Inter } from 'next/font/google'
|
|
203
|
+
const inter = Inter({ subsets: ['latin'] }) // Creates new instance each time!
|
|
204
|
+
|
|
205
|
+
// Good: Import once in layout, use CSS variable
|
|
206
|
+
// app/layout.tsx
|
|
207
|
+
const inter = Inter({ subsets: ['latin'], variable: '--font-inter' })
|
|
208
|
+
|
|
209
|
+
// Bad: Using @import in CSS (blocks rendering)
|
|
210
|
+
/* globals.css */
|
|
211
|
+
@import url('https://fonts.googleapis.com/css2?family=Inter');
|
|
212
|
+
|
|
213
|
+
// Good: Use next/font (self-hosted, no network request)
|
|
214
|
+
import { Inter } from 'next/font/google'
|
|
215
|
+
|
|
216
|
+
// Bad: Loading all weights when only using a few
|
|
217
|
+
const inter = Inter({ subsets: ['latin'] }) // Loads all weights
|
|
218
|
+
|
|
219
|
+
// Good: Specify only needed weights (for non-variable fonts)
|
|
220
|
+
const inter = Inter({ subsets: ['latin'], weight: ['400', '700'] })
|
|
221
|
+
|
|
222
|
+
// Bad: Missing subset - loads all characters
|
|
223
|
+
const inter = Inter({})
|
|
224
|
+
|
|
225
|
+
// Good: Always specify subset
|
|
226
|
+
const inter = Inter({ subsets: ['latin'] })
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Font in Specific Components
|
|
230
|
+
|
|
231
|
+
```tsx
|
|
232
|
+
// For component-specific fonts, export from a shared file
|
|
233
|
+
// lib/fonts.ts
|
|
234
|
+
import { Inter, Playfair_Display } from 'next/font/google'
|
|
235
|
+
|
|
236
|
+
export const inter = Inter({ subsets: ['latin'], variable: '--font-inter' })
|
|
237
|
+
export const playfair = Playfair_Display({ subsets: ['latin'], variable: '--font-playfair' })
|
|
238
|
+
|
|
239
|
+
// components/Heading.tsx
|
|
240
|
+
import { playfair } from '@/lib/fonts'
|
|
241
|
+
|
|
242
|
+
export function Heading({ children }) {
|
|
243
|
+
return <h1 className={playfair.className}>{children}</h1>
|
|
244
|
+
}
|
|
245
|
+
```
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Functions
|
|
2
|
+
|
|
3
|
+
Next.js function APIs.
|
|
4
|
+
|
|
5
|
+
Reference: https://nextjs.org/docs/app/api-reference/functions
|
|
6
|
+
|
|
7
|
+
## Navigation Hooks (Client)
|
|
8
|
+
|
|
9
|
+
| Hook | Purpose | Reference |
|
|
10
|
+
|------|---------|-----------|
|
|
11
|
+
| `useRouter` | Programmatic navigation (`push`, `replace`, `back`, `refresh`) | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-router) |
|
|
12
|
+
| `usePathname` | Get current pathname | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-pathname) |
|
|
13
|
+
| `useSearchParams` | Read URL search parameters | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-search-params) |
|
|
14
|
+
| `useParams` | Access dynamic route parameters | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-params) |
|
|
15
|
+
| `useSelectedLayoutSegment` | Active child segment (one level) | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-selected-layout-segment) |
|
|
16
|
+
| `useSelectedLayoutSegments` | All active segments below layout | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-selected-layout-segments) |
|
|
17
|
+
| `useLinkStatus` | Check link prefetch status | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-link-status) |
|
|
18
|
+
| `useReportWebVitals` | Report Core Web Vitals metrics | [Docs](https://nextjs.org/docs/app/api-reference/functions/use-report-web-vitals) |
|
|
19
|
+
|
|
20
|
+
## Server Functions
|
|
21
|
+
|
|
22
|
+
| Function | Purpose | Reference |
|
|
23
|
+
|----------|---------|-----------|
|
|
24
|
+
| `cookies` | Read/write cookies | [Docs](https://nextjs.org/docs/app/api-reference/functions/cookies) |
|
|
25
|
+
| `headers` | Read request headers | [Docs](https://nextjs.org/docs/app/api-reference/functions/headers) |
|
|
26
|
+
| `draftMode` | Enable preview of unpublished CMS content | [Docs](https://nextjs.org/docs/app/api-reference/functions/draft-mode) |
|
|
27
|
+
| `after` | Run code after response finishes streaming | [Docs](https://nextjs.org/docs/app/api-reference/functions/after) |
|
|
28
|
+
| `connection` | Wait for connection before dynamic rendering | [Docs](https://nextjs.org/docs/app/api-reference/functions/connection) |
|
|
29
|
+
| `userAgent` | Parse User-Agent header | [Docs](https://nextjs.org/docs/app/api-reference/functions/userAgent) |
|
|
30
|
+
|
|
31
|
+
## Generate Functions
|
|
32
|
+
|
|
33
|
+
| Function | Purpose | Reference |
|
|
34
|
+
|----------|---------|-----------|
|
|
35
|
+
| `generateStaticParams` | Pre-render dynamic routes at build time | [Docs](https://nextjs.org/docs/app/api-reference/functions/generate-static-params) |
|
|
36
|
+
| `generateMetadata` | Dynamic metadata | [Docs](https://nextjs.org/docs/app/api-reference/functions/generate-metadata) |
|
|
37
|
+
| `generateViewport` | Dynamic viewport config | [Docs](https://nextjs.org/docs/app/api-reference/functions/generate-viewport) |
|
|
38
|
+
| `generateSitemaps` | Multiple sitemaps for large sites | [Docs](https://nextjs.org/docs/app/api-reference/functions/generate-sitemaps) |
|
|
39
|
+
| `generateImageMetadata` | Multiple OG images per route | [Docs](https://nextjs.org/docs/app/api-reference/functions/generate-image-metadata) |
|
|
40
|
+
|
|
41
|
+
## Request/Response
|
|
42
|
+
|
|
43
|
+
| Function | Purpose | Reference |
|
|
44
|
+
|----------|---------|-----------|
|
|
45
|
+
| `NextRequest` | Extended Request with helpers | [Docs](https://nextjs.org/docs/app/api-reference/functions/next-request) |
|
|
46
|
+
| `NextResponse` | Extended Response with helpers | [Docs](https://nextjs.org/docs/app/api-reference/functions/next-response) |
|
|
47
|
+
| `ImageResponse` | Generate OG images | [Docs](https://nextjs.org/docs/app/api-reference/functions/image-response) |
|
|
48
|
+
|
|
49
|
+
## Common Examples
|
|
50
|
+
|
|
51
|
+
### Navigation
|
|
52
|
+
|
|
53
|
+
Use `next/link` for internal navigation instead of `<a>` tags.
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
// Bad: Plain anchor tag
|
|
57
|
+
<a href="/about">About</a>
|
|
58
|
+
|
|
59
|
+
// Good: Next.js Link
|
|
60
|
+
import Link from 'next/link'
|
|
61
|
+
|
|
62
|
+
<Link href="/about">About</Link>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Active link styling:
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
'use client'
|
|
69
|
+
|
|
70
|
+
import Link from 'next/link'
|
|
71
|
+
import { usePathname } from 'next/navigation'
|
|
72
|
+
|
|
73
|
+
export function NavLink({ href, children }) {
|
|
74
|
+
const pathname = usePathname()
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<Link href={href} className={pathname === href ? 'active' : ''}>
|
|
78
|
+
{children}
|
|
79
|
+
</Link>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Static Generation
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
// app/blog/[slug]/page.tsx
|
|
88
|
+
export async function generateStaticParams() {
|
|
89
|
+
const posts = await getPosts()
|
|
90
|
+
return posts.map((post) => ({ slug: post.slug }))
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### After Response
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
import { after } from 'next/server'
|
|
98
|
+
|
|
99
|
+
export async function POST(request: Request) {
|
|
100
|
+
const data = await processRequest(request)
|
|
101
|
+
|
|
102
|
+
after(async () => {
|
|
103
|
+
await logAnalytics(data)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
return Response.json({ success: true })
|
|
107
|
+
}
|
|
108
|
+
```
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Hydration Errors
|
|
2
|
+
|
|
3
|
+
Diagnose and fix React hydration mismatch errors.
|
|
4
|
+
|
|
5
|
+
## Error Signs
|
|
6
|
+
|
|
7
|
+
- "Hydration failed because the initial UI does not match"
|
|
8
|
+
- "Text content does not match server-rendered HTML"
|
|
9
|
+
|
|
10
|
+
## Debugging
|
|
11
|
+
|
|
12
|
+
In development, click the hydration error to see the server/client diff.
|
|
13
|
+
|
|
14
|
+
## Common Causes and Fixes
|
|
15
|
+
|
|
16
|
+
### Browser-only APIs
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
// Bad: Causes mismatch - window doesn't exist on server
|
|
20
|
+
<div>{window.innerWidth}</div>
|
|
21
|
+
|
|
22
|
+
// Good: Use client component with mounted check
|
|
23
|
+
'use client'
|
|
24
|
+
import { useState, useEffect } from 'react'
|
|
25
|
+
|
|
26
|
+
export function ClientOnly({ children }: { children: React.ReactNode }) {
|
|
27
|
+
const [mounted, setMounted] = useState(false)
|
|
28
|
+
useEffect(() => setMounted(true), [])
|
|
29
|
+
return mounted ? children : null
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Date/Time Rendering
|
|
34
|
+
|
|
35
|
+
Server and client may be in different timezones:
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
// Bad: Causes mismatch
|
|
39
|
+
<span>{new Date().toLocaleString()}</span>
|
|
40
|
+
|
|
41
|
+
// Good: Render on client only
|
|
42
|
+
'use client'
|
|
43
|
+
const [time, setTime] = useState<string>()
|
|
44
|
+
useEffect(() => setTime(new Date().toLocaleString()), [])
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Random Values or IDs
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
// Bad: Random values differ between server and client
|
|
51
|
+
<div id={Math.random().toString()}>
|
|
52
|
+
|
|
53
|
+
// Good: Use useId hook
|
|
54
|
+
import { useId } from 'react'
|
|
55
|
+
|
|
56
|
+
function Input() {
|
|
57
|
+
const id = useId()
|
|
58
|
+
return <input id={id} />
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Invalid HTML Nesting
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
// Bad: Invalid - div inside p
|
|
66
|
+
<p><div>Content</div></p>
|
|
67
|
+
|
|
68
|
+
// Bad: Invalid - p inside p
|
|
69
|
+
<p><p>Nested</p></p>
|
|
70
|
+
|
|
71
|
+
// Good: Valid nesting
|
|
72
|
+
<div><p>Content</p></div>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Third-party Scripts
|
|
76
|
+
|
|
77
|
+
Scripts that modify DOM during hydration.
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
// Good: Use next/script with afterInteractive
|
|
81
|
+
import Script from 'next/script'
|
|
82
|
+
|
|
83
|
+
export default function Page() {
|
|
84
|
+
return (
|
|
85
|
+
<Script
|
|
86
|
+
src="https://example.com/script.js"
|
|
87
|
+
strategy="afterInteractive"
|
|
88
|
+
/>
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
```
|