From f6bcc86881a45d39ee28924412ea9c2e77943430 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Mon, 16 Feb 2026 16:17:40 -0600 Subject: [PATCH] feat: Add 5 curated skills for Mosaic Stack New skills: - next-best-practices: Next.js 15+ RSC, async patterns, self-hosting (vercel-labs) - better-auth-best-practices: Official Better-Auth with Drizzle adapter (better-auth) - verification-before-completion: Evidence-based completion claims (obra/superpowers) - shadcn-ui: Component patterns with Tailwind v4 adaptation note (developer-kit) - writing-skills: TDD methodology for skill authoring (obra/superpowers) README reorganized by category with Mosaic Stack alignment section. Total: 9 skills (4 existing + 5 new). Co-Authored-By: Claude Opus 4.6 --- README.md | 56 +- skills/better-auth-best-practices/SKILL.md | 166 ++ skills/next-best-practices/SKILL.md | 153 ++ skills/next-best-practices/async-patterns.md | 87 + skills/next-best-practices/bundling.md | 180 ++ skills/next-best-practices/data-patterns.md | 297 +++ skills/next-best-practices/debug-tricks.md | 105 + skills/next-best-practices/directives.md | 73 + skills/next-best-practices/error-handling.md | 227 ++ .../next-best-practices/file-conventions.md | 140 ++ skills/next-best-practices/font.md | 245 +++ skills/next-best-practices/functions.md | 108 + skills/next-best-practices/hydration-error.md | 91 + skills/next-best-practices/image.md | 173 ++ skills/next-best-practices/metadata.md | 301 +++ skills/next-best-practices/parallel-routes.md | 287 +++ skills/next-best-practices/route-handlers.md | 146 ++ skills/next-best-practices/rsc-boundaries.md | 159 ++ .../next-best-practices/runtime-selection.md | 39 + skills/next-best-practices/scripts.md | 141 ++ skills/next-best-practices/self-hosting.md | 371 ++++ .../suspense-boundaries.md | 67 + skills/shadcn-ui/SKILL.md | 1932 +++++++++++++++++ skills/shadcn-ui/references/chart.md | 306 +++ skills/shadcn-ui/references/learn.md | 145 ++ .../references/official-ui-reference.md | 1725 +++++++++++++++ skills/shadcn-ui/references/reference.md | 586 +++++ skills/shadcn-ui/references/ui-reference.md | 1578 ++++++++++++++ .../verification-before-completion/SKILL.md | 139 ++ skills/writing-skills/SKILL.md | 655 ++++++ .../anthropic-best-practices.md | 1150 ++++++++++ .../examples/CLAUDE_MD_TESTING.md | 189 ++ .../writing-skills/graphviz-conventions.dot | 172 ++ .../writing-skills/persuasion-principles.md | 187 ++ skills/writing-skills/render-graphs.js | 168 ++ .../testing-skills-with-subagents.md | 384 ++++ 36 files changed, 12921 insertions(+), 7 deletions(-) create mode 100644 skills/better-auth-best-practices/SKILL.md create mode 100644 skills/next-best-practices/SKILL.md create mode 100644 skills/next-best-practices/async-patterns.md create mode 100644 skills/next-best-practices/bundling.md create mode 100644 skills/next-best-practices/data-patterns.md create mode 100644 skills/next-best-practices/debug-tricks.md create mode 100644 skills/next-best-practices/directives.md create mode 100644 skills/next-best-practices/error-handling.md create mode 100644 skills/next-best-practices/file-conventions.md create mode 100644 skills/next-best-practices/font.md create mode 100644 skills/next-best-practices/functions.md create mode 100644 skills/next-best-practices/hydration-error.md create mode 100644 skills/next-best-practices/image.md create mode 100644 skills/next-best-practices/metadata.md create mode 100644 skills/next-best-practices/parallel-routes.md create mode 100644 skills/next-best-practices/route-handlers.md create mode 100644 skills/next-best-practices/rsc-boundaries.md create mode 100644 skills/next-best-practices/runtime-selection.md create mode 100644 skills/next-best-practices/scripts.md create mode 100644 skills/next-best-practices/self-hosting.md create mode 100644 skills/next-best-practices/suspense-boundaries.md create mode 100644 skills/shadcn-ui/SKILL.md create mode 100644 skills/shadcn-ui/references/chart.md create mode 100644 skills/shadcn-ui/references/learn.md create mode 100644 skills/shadcn-ui/references/official-ui-reference.md create mode 100644 skills/shadcn-ui/references/reference.md create mode 100644 skills/shadcn-ui/references/ui-reference.md create mode 100644 skills/verification-before-completion/SKILL.md create mode 100644 skills/writing-skills/SKILL.md create mode 100644 skills/writing-skills/anthropic-best-practices.md create mode 100644 skills/writing-skills/examples/CLAUDE_MD_TESTING.md create mode 100644 skills/writing-skills/graphviz-conventions.dot create mode 100644 skills/writing-skills/persuasion-principles.md create mode 100755 skills/writing-skills/render-graphs.js create mode 100644 skills/writing-skills/testing-skills-with-subagents.md diff --git a/README.md b/README.md index ea7b472..5679d5e 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,49 @@ Custom agent skills for Mosaic Stack and USC projects. Platform-aware — works ## Skills +### Code Quality & Review + | Skill | Purpose | Origin | |-------|---------|--------| | `pr-reviewer` | Structured PR code review workflow | Adapted from [SpillwaveSolutions/pr-reviewer-skill](https://github.com/SpillwaveSolutions/pr-reviewer-skill) | | `code-review-excellence` | Code review methodology and checklists | Adapted from [awesome-skills/code-review-skill](https://github.com/awesome-skills/code-review-skill) | -| `vercel-react-best-practices` | React/Next.js performance optimization | From [vercel-labs/agent-skills](https://github.com/vercel-labs/agent-skills) | +| `verification-before-completion` | Evidence-based completion claims — no success without verification | From [obra/superpowers](https://github.com/obra/superpowers) | + +### Frontend & UI + +| Skill | Purpose | Origin | +|-------|---------|--------| +| `next-best-practices` | Next.js 15+ best practices — RSC, async patterns, self-hosting, data patterns | From [vercel-labs/next-skills](https://github.com/vercel-labs/next-skills) | +| `vercel-react-best-practices` | React/Next.js performance optimization (57 rules) | From [vercel-labs/agent-skills](https://github.com/vercel-labs/agent-skills) | +| `shadcn-ui` | shadcn/ui component patterns — forms, dialogs, tables, charts | From [giuseppe-trisciuoglio/developer-kit](https://github.com/giuseppe-trisciuoglio/developer-kit) | | `tailwind-design-system` | Tailwind CSS v4 design system patterns | Adapted from [wshobson/agents](https://github.com/wshobson/agents) | +### Authentication + +| Skill | Purpose | Origin | +|-------|---------|--------| +| `better-auth-best-practices` | Better-Auth integration — Drizzle adapter, sessions, plugins, security | From [better-auth/skills](https://github.com/better-auth/skills) | + +### Meta / Skill Authoring + +| Skill | Purpose | Origin | +|-------|---------|--------| +| `writing-skills` | TDD-based methodology for creating and testing agent skills | From [obra/superpowers](https://github.com/obra/superpowers) | + +## Mosaic Stack Alignment + +These skills are curated for the Mosaic Stack tech stack: + +- **Backend:** NestJS + TypeScript +- **Frontend:** Next.js 15 + React 19 (App Router) +- **Styling:** Tailwind CSS v4 + shadcn/ui +- **Auth:** Better-Auth with Drizzle adapter +- **Database:** PostgreSQL + Drizzle ORM +- **CI/CD:** Woodpecker CI / Gitea +- **Deployment:** Docker Swarm + +Skills are either used as-is (when framework-agnostic or matching our stack) or adapted with Mosaic Stack-specific notes where upstream assumptions differ (e.g., shadcn-ui references Tailwind v3 config patterns). + ## Installation ### Via npx (recommended) @@ -36,11 +72,16 @@ npx skills add https://git.mosaicstack.dev/mosaic/agent-skills.git --skill pr-re # Clone the repo git clone https://git.mosaicstack.dev/mosaic/agent-skills.git ~/src/agent-skills -# Symlink individual skills +# Symlink all skills +for skill in ~/src/agent-skills/skills/*/; do + ln -sf "$skill" ~/.claude/skills/$(basename "$skill") +done + +# Or symlink individually ln -sf ~/src/agent-skills/skills/pr-reviewer ~/.claude/skills/pr-reviewer -ln -sf ~/src/agent-skills/skills/code-review-excellence ~/.claude/skills/code-review-excellence -ln -sf ~/src/agent-skills/skills/vercel-react-best-practices ~/.claude/skills/vercel-react-best-practices -ln -sf ~/src/agent-skills/skills/tailwind-design-system ~/.claude/skills/tailwind-design-system +ln -sf ~/src/agent-skills/skills/next-best-practices ~/.claude/skills/next-best-practices +ln -sf ~/src/agent-skills/skills/better-auth-best-practices ~/.claude/skills/better-auth-best-practices +# ... etc ``` ### Per-Project @@ -50,7 +91,7 @@ Symlink into a project's `.claude/skills/` directory for project-specific availa ## Dependencies - `~/.claude/scripts/git/` — Platform-aware git scripts (detect-platform, pr-view, pr-diff, pr-metadata, pr-review, etc.) -- `python3` — For review file generation +- `python3` — For review file generation (pr-reviewer) ## Adapting Skills @@ -59,7 +100,8 @@ When adding skills from the community: 1. Replace raw `gh`/`tea` calls with our `~/.claude/scripts/git/` scripts 2. Test on both GitHub and Gitea repos 3. Remove features that don't work cross-platform (e.g., GitHub-specific inline comments) -4. Document any platform-specific limitations +4. Add Mosaic Stack context notes where upstream assumptions differ from our stack +5. Document any platform-specific limitations ## License diff --git a/skills/better-auth-best-practices/SKILL.md b/skills/better-auth-best-practices/SKILL.md new file mode 100644 index 0000000..3458e07 --- /dev/null +++ b/skills/better-auth-best-practices/SKILL.md @@ -0,0 +1,166 @@ +--- +name: better-auth-best-practices +description: Skill for integrating Better Auth - the comprehensive TypeScript authentication framework. +--- + +# Better Auth Integration Guide + +**Always consult [better-auth.com/docs](https://better-auth.com/docs) for code examples and latest API.** + +Better Auth is a TypeScript-first, framework-agnostic auth framework supporting email/password, OAuth, magic links, passkeys, and more via plugins. + +--- + +## Quick Reference + +### Environment Variables +- `BETTER_AUTH_SECRET` - Encryption secret (min 32 chars). Generate: `openssl rand -base64 32` +- `BETTER_AUTH_URL` - Base URL (e.g., `https://example.com`) + +Only define `baseURL`/`secret` in config if env vars are NOT set. + +### File Location +CLI looks for `auth.ts` in: `./`, `./lib`, `./utils`, or under `./src`. Use `--config` for custom path. + +### CLI Commands +- `npx @better-auth/cli@latest migrate` - Apply schema (built-in adapter) +- `npx @better-auth/cli@latest generate` - Generate schema for Prisma/Drizzle +- `npx @better-auth/cli mcp --cursor` - Add MCP to AI tools + +**Re-run after adding/changing plugins.** + +--- + +## Core Config Options + +| Option | Notes | +|--------|-------| +| `appName` | Optional display name | +| `baseURL` | Only if `BETTER_AUTH_URL` not set | +| `basePath` | Default `/api/auth`. Set `/` for root. | +| `secret` | Only if `BETTER_AUTH_SECRET` not set | +| `database` | Required for most features. See adapters docs. | +| `secondaryStorage` | Redis/KV for sessions & rate limits | +| `emailAndPassword` | `{ enabled: true }` to activate | +| `socialProviders` | `{ google: { clientId, clientSecret }, ... }` | +| `plugins` | Array of plugins | +| `trustedOrigins` | CSRF whitelist | + +--- + +## Database + +**Direct connections:** Pass `pg.Pool`, `mysql2` pool, `better-sqlite3`, or `bun:sqlite` instance. + +**ORM adapters:** Import from `better-auth/adapters/drizzle`, `better-auth/adapters/prisma`, `better-auth/adapters/mongodb`. + +**Critical:** Better Auth uses adapter model names, NOT underlying table names. If Prisma model is `User` mapping to table `users`, use `modelName: "user"` (Prisma reference), not `"users"`. + +--- + +## Session Management + +**Storage priority:** +1. If `secondaryStorage` defined → sessions go there (not DB) +2. Set `session.storeSessionInDatabase: true` to also persist to DB +3. No database + `cookieCache` → fully stateless mode + +**Cookie cache strategies:** +- `compact` (default) - Base64url + HMAC. Smallest. +- `jwt` - Standard JWT. Readable but signed. +- `jwe` - Encrypted. Maximum security. + +**Key options:** `session.expiresIn` (default 7 days), `session.updateAge` (refresh interval), `session.cookieCache.maxAge`, `session.cookieCache.version` (change to invalidate all sessions). + +--- + +## User & Account Config + +**User:** `user.modelName`, `user.fields` (column mapping), `user.additionalFields`, `user.changeEmail.enabled` (disabled by default), `user.deleteUser.enabled` (disabled by default). + +**Account:** `account.modelName`, `account.accountLinking.enabled`, `account.storeAccountCookie` (for stateless OAuth). + +**Required for registration:** `email` and `name` fields. + +--- + +## Email Flows + +- `emailVerification.sendVerificationEmail` - Must be defined for verification to work +- `emailVerification.sendOnSignUp` / `sendOnSignIn` - Auto-send triggers +- `emailAndPassword.sendResetPassword` - Password reset email handler + +--- + +## Security + +**In `advanced`:** +- `useSecureCookies` - Force HTTPS cookies +- `disableCSRFCheck` - ⚠️ Security risk +- `disableOriginCheck` - ⚠️ Security risk +- `crossSubDomainCookies.enabled` - Share cookies across subdomains +- `ipAddress.ipAddressHeaders` - Custom IP headers for proxies +- `database.generateId` - Custom ID generation or `"serial"`/`"uuid"`/`false` + +**Rate limiting:** `rateLimit.enabled`, `rateLimit.window`, `rateLimit.max`, `rateLimit.storage` ("memory" | "database" | "secondary-storage"). + +--- + +## Hooks + +**Endpoint hooks:** `hooks.before` / `hooks.after` - Array of `{ matcher, handler }`. Use `createAuthMiddleware`. Access `ctx.path`, `ctx.context.returned` (after), `ctx.context.session`. + +**Database hooks:** `databaseHooks.user.create.before/after`, same for `session`, `account`. Useful for adding default values or post-creation actions. + +**Hook context (`ctx.context`):** `session`, `secret`, `authCookies`, `password.hash()`/`verify()`, `adapter`, `internalAdapter`, `generateId()`, `tables`, `baseURL`. + +--- + +## Plugins + +**Import from dedicated paths for tree-shaking:** +``` +import { twoFactor } from "better-auth/plugins/two-factor" +``` +NOT `from "better-auth/plugins"`. + +**Popular plugins:** `twoFactor`, `organization`, `passkey`, `magicLink`, `emailOtp`, `username`, `phoneNumber`, `admin`, `apiKey`, `bearer`, `jwt`, `multiSession`, `sso`, `oauthProvider`, `oidcProvider`, `openAPI`, `genericOAuth`. + +Client plugins go in `createAuthClient({ plugins: [...] })`. + +--- + +## Client + +Import from: `better-auth/client` (vanilla), `better-auth/react`, `better-auth/vue`, `better-auth/svelte`, `better-auth/solid`. + +Key methods: `signUp.email()`, `signIn.email()`, `signIn.social()`, `signOut()`, `useSession()`, `getSession()`, `revokeSession()`, `revokeSessions()`. + +--- + +## Type Safety + +Infer types: `typeof auth.$Infer.Session`, `typeof auth.$Infer.Session.user`. + +For separate client/server projects: `createAuthClient()`. + +--- + +## Common Gotchas + +1. **Model vs table name** - Config uses ORM model name, not DB table name +2. **Plugin schema** - Re-run CLI after adding plugins +3. **Secondary storage** - Sessions go there by default, not DB +4. **Cookie cache** - Custom session fields NOT cached, always re-fetched +5. **Stateless mode** - No DB = session in cookie only, logout on cache expiry +6. **Change email flow** - Sends to current email first, then new email + +--- + +## Resources + +- [Docs](https://better-auth.com/docs) +- [Options Reference](https://better-auth.com/docs/reference/options) +- [LLMs.txt](https://better-auth.com/llms.txt) +- [GitHub](https://github.com/better-auth/better-auth) +- [Init Options Source](https://github.com/better-auth/better-auth/blob/main/packages/core/src/types/init-options.ts) \ No newline at end of file diff --git a/skills/next-best-practices/SKILL.md b/skills/next-best-practices/SKILL.md new file mode 100644 index 0000000..437896b --- /dev/null +++ b/skills/next-best-practices/SKILL.md @@ -0,0 +1,153 @@ +--- +name: next-best-practices +description: Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling +user-invocable: false +--- + +# Next.js Best Practices + +Apply these rules when writing or reviewing Next.js code. + +## File Conventions + +See [file-conventions.md](./file-conventions.md) for: +- Project structure and special files +- Route segments (dynamic, catch-all, groups) +- Parallel and intercepting routes +- Middleware rename in v16 (middleware → proxy) + +## RSC Boundaries + +Detect invalid React Server Component patterns. + +See [rsc-boundaries.md](./rsc-boundaries.md) for: +- Async client component detection (invalid) +- Non-serializable props detection +- Server Action exceptions + +## Async Patterns + +Next.js 15+ async API changes. + +See [async-patterns.md](./async-patterns.md) for: +- Async `params` and `searchParams` +- Async `cookies()` and `headers()` +- Migration codemod + +## Runtime Selection + +See [runtime-selection.md](./runtime-selection.md) for: +- Default to Node.js runtime +- When Edge runtime is appropriate + +## Directives + +See [directives.md](./directives.md) for: +- `'use client'`, `'use server'` (React) +- `'use cache'` (Next.js) + +## Functions + +See [functions.md](./functions.md) for: +- Navigation hooks: `useRouter`, `usePathname`, `useSearchParams`, `useParams` +- Server functions: `cookies`, `headers`, `draftMode`, `after` +- Generate functions: `generateStaticParams`, `generateMetadata` + +## Error Handling + +See [error-handling.md](./error-handling.md) for: +- `error.tsx`, `global-error.tsx`, `not-found.tsx` +- `redirect`, `permanentRedirect`, `notFound` +- `forbidden`, `unauthorized` (auth errors) +- `unstable_rethrow` for catch blocks + +## Data Patterns + +See [data-patterns.md](./data-patterns.md) for: +- Server Components vs Server Actions vs Route Handlers +- Avoiding data waterfalls (`Promise.all`, Suspense, preload) +- Client component data fetching + +## Route Handlers + +See [route-handlers.md](./route-handlers.md) for: +- `route.ts` basics +- GET handler conflicts with `page.tsx` +- Environment behavior (no React DOM) +- When to use vs Server Actions + +## Metadata & OG Images + +See [metadata.md](./metadata.md) for: +- Static and dynamic metadata +- `generateMetadata` function +- OG image generation with `next/og` +- File-based metadata conventions + +## Image Optimization + +See [image.md](./image.md) for: +- Always use `next/image` over `` +- Remote images configuration +- Responsive `sizes` attribute +- Blur placeholders +- Priority loading for LCP + +## Font Optimization + +See [font.md](./font.md) for: +- `next/font` setup +- Google Fonts, local fonts +- Tailwind CSS integration +- Preloading subsets + +## Bundling + +See [bundling.md](./bundling.md) for: +- Server-incompatible packages +- CSS imports (not link tags) +- Polyfills (already included) +- ESM/CommonJS issues +- Bundle analysis + +## Scripts + +See [scripts.md](./scripts.md) for: +- `next/script` vs native script tags +- Inline scripts need `id` +- Loading strategies +- Google Analytics with `@next/third-parties` + +## Hydration Errors + +See [hydration-error.md](./hydration-error.md) for: +- Common causes (browser APIs, dates, invalid HTML) +- Debugging with error overlay +- Fixes for each cause + +## Suspense Boundaries + +See [suspense-boundaries.md](./suspense-boundaries.md) for: +- CSR bailout with `useSearchParams` and `usePathname` +- Which hooks require Suspense boundaries + +## Parallel & Intercepting Routes + +See [parallel-routes.md](./parallel-routes.md) for: +- Modal patterns with `@slot` and `(.)` interceptors +- `default.tsx` for fallbacks +- Closing modals correctly with `router.back()` + +## Self-Hosting + +See [self-hosting.md](./self-hosting.md) for: +- `output: 'standalone'` for Docker +- Cache handlers for multi-instance ISR +- What works vs needs extra setup + +## Debug Tricks + +See [debug-tricks.md](./debug-tricks.md) for: +- MCP endpoint for AI-assisted debugging +- Rebuild specific routes with `--debug-build-paths` + diff --git a/skills/next-best-practices/async-patterns.md b/skills/next-best-practices/async-patterns.md new file mode 100644 index 0000000..dce8d8c --- /dev/null +++ b/skills/next-best-practices/async-patterns.md @@ -0,0 +1,87 @@ +# Async Patterns + +In Next.js 15+, `params`, `searchParams`, `cookies()`, and `headers()` are asynchronous. + +## Async Params and SearchParams + +Always type them as `Promise<...>` and await them. + +### Pages and Layouts + +```tsx +type Props = { params: Promise<{ slug: string }> } + +export default async function Page({ params }: Props) { + const { slug } = await params +} +``` + +### Route Handlers + +```tsx +export async function GET( + request: Request, + { params }: { params: Promise<{ id: string }> } +) { + const { id } = await params +} +``` + +### SearchParams + +```tsx +type Props = { + params: Promise<{ slug: string }> + searchParams: Promise<{ query?: string }> +} + +export default async function Page({ params, searchParams }: Props) { + const { slug } = await params + const { query } = await searchParams +} +``` + +### Synchronous Components + +Use `React.use()` for non-async components: + +```tsx +import { use } from 'react' + +type Props = { params: Promise<{ slug: string }> } + +export default function Page({ params }: Props) { + const { slug } = use(params) +} +``` + +### generateMetadata + +```tsx +type Props = { params: Promise<{ slug: string }> } + +export async function generateMetadata({ params }: Props): Promise { + const { slug } = await params + return { title: slug } +} +``` + +## Async Cookies and Headers + +```tsx +import { cookies, headers } from 'next/headers' + +export default async function Page() { + const cookieStore = await cookies() + const headersList = await headers() + + const theme = cookieStore.get('theme') + const userAgent = headersList.get('user-agent') +} +``` + +## Migration Codemod + +```bash +npx @next/codemod@latest next-async-request-api . +``` diff --git a/skills/next-best-practices/bundling.md b/skills/next-best-practices/bundling.md new file mode 100644 index 0000000..ac5e814 --- /dev/null +++ b/skills/next-best-practices/bundling.md @@ -0,0 +1,180 @@ +# Bundling + +Fix common bundling issues with third-party packages. + +## Server-Incompatible Packages + +Some packages use browser APIs (`window`, `document`, `localStorage`) and fail in Server Components. + +### Error Signs + +``` +ReferenceError: window is not defined +ReferenceError: document is not defined +ReferenceError: localStorage is not defined +Module not found: Can't resolve 'fs' +``` + +### Solution 1: Mark as Client-Only + +If the package is only needed on client: + +```tsx +// Bad: Fails - package uses window +import SomeChart from 'some-chart-library' + +export default function Page() { + return +} + +// Good: Use dynamic import with ssr: false +import dynamic from 'next/dynamic' + +const SomeChart = dynamic(() => import('some-chart-library'), { + ssr: false, +}) + +export default function Page() { + return +} +``` + +### Solution 2: Externalize from Server Bundle + +For packages that should run on server but have bundling issues: + +```js +// next.config.js +module.exports = { + serverExternalPackages: ['problematic-package'], +} +``` + +Use this for: +- Packages with native bindings (sharp, bcrypt) +- Packages that don't bundle well (some ORMs) +- Packages with circular dependencies + +### Solution 3: Client Component Wrapper + +Wrap the entire usage in a client component: + +```tsx +// components/ChartWrapper.tsx +'use client' + +import { Chart } from 'chart-library' + +export function ChartWrapper(props) { + return +} + +// app/page.tsx (server component) +import { ChartWrapper } from '@/components/ChartWrapper' + +export default function Page() { + return +} +``` + +## CSS Imports + +Import CSS files instead of using `` tags. Next.js handles bundling and optimization. + +```tsx +// Bad: Manual link tag + + +// Good: Import CSS +import './styles.css' + +// Good: CSS Modules +import styles from './Button.module.css' +``` + +## Polyfills + +Next.js includes common polyfills automatically. Don't load redundant ones from polyfill.io or similar CDNs. + +Already included: `Array.from`, `Object.assign`, `Promise`, `fetch`, `Map`, `Set`, `Symbol`, `URLSearchParams`, and 50+ others. + +```tsx +// Bad: Redundant polyfills + + +// Good: Next.js Script component +import Script from 'next/script' + + +``` + +## Don't Put Script in Head + +`next/script` should not be placed inside `next/head`. It handles its own positioning. + +```tsx +// Bad: Script inside Head +import Head from 'next/head' +import Script from 'next/script' + + + + +// Good: Next.js component +import { GoogleAnalytics } from '@next/third-parties/google' + +export default function Layout({ children }) { + return ( + + {children} + + + ) +} +``` + +## Google Tag Manager + +```tsx +import { GoogleTagManager } from '@next/third-parties/google' + +export default function Layout({ children }) { + return ( + + + {children} + + ) +} +``` + +## Other Third-Party Scripts + +```tsx +// YouTube embed +import { YouTubeEmbed } from '@next/third-parties/google' + + + +// Google Maps +import { GoogleMapsEmbed } from '@next/third-parties/google' + + +``` + +## Quick Reference + +| Pattern | Issue | Fix | +|---------|-------|-----| +| `