From 4aa805c60f2d1c73ca49bb3a2a19dc07ed411919 Mon Sep 17 00:00:00 2001 From: sangwook yoo Date: Tue, 12 May 2026 18:00:26 +0900 Subject: [PATCH 1/8] =?UTF-8?q?chore:=20gitignore=20=EC=97=90=20graphify-o?= =?UTF-8?q?ut/=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit graphify 지식 그래프 산출물(AST 캐시·graph.json·HTML·리포트)은 로컬 캐시이며 post-commit hook 으로 자동 갱신되므로 git 추적에서 제외. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 1554dc5b..ba6d2ed1 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,9 @@ last_updated.log claude-501/ sl +# [graphify 2026-05-12] graphify 지식 그래프 산출물 (로컬 캐시, post-commit hook 으로 자동 갱신) +graphify-out/ + # [local-only 2026-05-08] 모든 markdown 문서 + Claude 설정은 git 추적 제외 (로컬 전용) # 단, 루트 README.md 만 추적 유지 *.md -- 2.47.2 From 3ac66feba255109baf63809130d995cb475632a0 Mon Sep 17 00:00:00 2001 From: sangwook yoo Date: Tue, 12 May 2026 18:05:03 +0900 Subject: [PATCH 2/8] =?UTF-8?q?chore:=20.agents/.claude=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=C2=B7CLAUDE.md=C2=B7AGENTS.md=20git=20=EC=B6=94?= =?UTF-8?q?=EC=A0=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gitignore 의 *.md / .claude/ 차단을 풀어 다음 파일을 git 으로 추적. - /CLAUDE.md, /AGENTS.md (루트 에이전트 가이드) - .agents/**/*.md (skills 문서 95개) - .claude/settings.json (Claude Code 프로젝트 설정) .claude/worktrees/ 는 git worktree 메타이므로 신규 ignore 라인으로 제외. Co-Authored-By: Claude Opus 4.7 (1M context) --- .agents/skills/next-best-practices/SKILL.md | 153 + .../next-best-practices/async-patterns.md | 87 + .../skills/next-best-practices/bundling.md | 180 + .../next-best-practices/data-patterns.md | 297 ++ .../next-best-practices/debug-tricks.md | 105 + .../skills/next-best-practices/directives.md | 73 + .../next-best-practices/error-handling.md | 227 + .../next-best-practices/file-conventions.md | 140 + .agents/skills/next-best-practices/font.md | 245 ++ .../skills/next-best-practices/functions.md | 108 + .../next-best-practices/hydration-error.md | 91 + .agents/skills/next-best-practices/image.md | 173 + .../skills/next-best-practices/metadata.md | 301 ++ .../next-best-practices/parallel-routes.md | 287 ++ .../next-best-practices/route-handlers.md | 146 + .../next-best-practices/rsc-boundaries.md | 159 + .../next-best-practices/runtime-selection.md | 39 + .agents/skills/next-best-practices/scripts.md | 141 + .../next-best-practices/self-hosting.md | 371 ++ .../suspense-boundaries.md | 67 + .../vercel-react-best-practices/AGENTS.md | 3810 +++++++++++++++++ .../vercel-react-best-practices/README.md | 123 + .../vercel-react-best-practices/SKILL.md | 149 + .../rules/_sections.md | 46 + .../rules/_template.md | 28 + .../rules/advanced-effect-event-deps.md | 56 + .../rules/advanced-event-handler-refs.md | 55 + .../rules/advanced-init-once.md | 42 + .../rules/advanced-use-latest.md | 39 + .../rules/async-api-routes.md | 38 + .../async-cheap-condition-before-await.md | 37 + .../rules/async-defer-await.md | 82 + .../rules/async-dependencies.md | 51 + .../rules/async-parallel.md | 28 + .../rules/async-suspense-boundaries.md | 99 + .../rules/bundle-analyzable-paths.md | 63 + .../rules/bundle-barrel-imports.md | 60 + .../rules/bundle-conditional.md | 31 + .../rules/bundle-defer-third-party.md | 49 + .../rules/bundle-dynamic-imports.md | 35 + .../rules/bundle-preload.md | 50 + .../rules/client-event-listeners.md | 74 + .../rules/client-localstorage-schema.md | 71 + .../rules/client-passive-event-listeners.md | 48 + .../rules/client-swr-dedup.md | 56 + .../rules/js-batch-dom-css.md | 107 + .../rules/js-cache-function-results.md | 80 + .../rules/js-cache-property-access.md | 28 + .../rules/js-cache-storage.md | 70 + .../rules/js-combine-iterations.md | 32 + .../rules/js-early-exit.md | 50 + .../rules/js-flatmap-filter.md | 60 + .../rules/js-hoist-regexp.md | 45 + .../rules/js-index-maps.md | 37 + .../rules/js-length-check-first.md | 49 + .../rules/js-min-max-loop.md | 82 + .../rules/js-request-idle-callback.md | 105 + .../rules/js-set-map-lookups.md | 24 + .../rules/js-tosorted-immutable.md | 57 + .../rules/rendering-activity.md | 26 + .../rules/rendering-animate-svg-wrapper.md | 47 + .../rules/rendering-conditional-render.md | 40 + .../rules/rendering-content-visibility.md | 38 + .../rules/rendering-hoist-jsx.md | 46 + .../rules/rendering-hydration-no-flicker.md | 82 + .../rendering-hydration-suppress-warning.md | 30 + .../rules/rendering-resource-hints.md | 85 + .../rules/rendering-script-defer-async.md | 68 + .../rules/rendering-svg-precision.md | 28 + .../rules/rendering-usetransition-loading.md | 75 + .../rules/rerender-defer-reads.md | 39 + .../rules/rerender-dependencies.md | 45 + .../rules/rerender-derived-state-no-effect.md | 40 + .../rules/rerender-derived-state.md | 29 + .../rules/rerender-functional-setstate.md | 74 + .../rules/rerender-lazy-state-init.md | 58 + .../rules/rerender-memo-with-default-value.md | 38 + .../rules/rerender-memo.md | 44 + .../rules/rerender-move-effect-to-event.md | 45 + .../rules/rerender-no-inline-components.md | 82 + .../rerender-simple-expression-in-memo.md | 35 + .../rules/rerender-split-combined-hooks.md | 64 + .../rules/rerender-transitions.md | 40 + .../rules/rerender-use-deferred-value.md | 59 + .../rerender-use-ref-transient-values.md | 73 + .../rules/server-after-nonblocking.md | 73 + .../rules/server-auth-actions.md | 96 + .../rules/server-cache-lru.md | 41 + .../rules/server-cache-react.md | 76 + .../rules/server-dedup-props.md | 65 + .../rules/server-hoist-static-io.md | 149 + .../rules/server-no-shared-module-state.md | 50 + .../rules/server-parallel-fetching.md | 83 + .../rules/server-parallel-nested-fetching.md | 34 + .../rules/server-serialization.md | 38 + .claude/settings.json | 15 + .gitignore | 12 +- AGENTS.md | 1 + CLAUDE.md | 110 + 99 files changed, 11606 insertions(+), 3 deletions(-) create mode 100644 .agents/skills/next-best-practices/SKILL.md create mode 100644 .agents/skills/next-best-practices/async-patterns.md create mode 100644 .agents/skills/next-best-practices/bundling.md create mode 100644 .agents/skills/next-best-practices/data-patterns.md create mode 100644 .agents/skills/next-best-practices/debug-tricks.md create mode 100644 .agents/skills/next-best-practices/directives.md create mode 100644 .agents/skills/next-best-practices/error-handling.md create mode 100644 .agents/skills/next-best-practices/file-conventions.md create mode 100644 .agents/skills/next-best-practices/font.md create mode 100644 .agents/skills/next-best-practices/functions.md create mode 100644 .agents/skills/next-best-practices/hydration-error.md create mode 100644 .agents/skills/next-best-practices/image.md create mode 100644 .agents/skills/next-best-practices/metadata.md create mode 100644 .agents/skills/next-best-practices/parallel-routes.md create mode 100644 .agents/skills/next-best-practices/route-handlers.md create mode 100644 .agents/skills/next-best-practices/rsc-boundaries.md create mode 100644 .agents/skills/next-best-practices/runtime-selection.md create mode 100644 .agents/skills/next-best-practices/scripts.md create mode 100644 .agents/skills/next-best-practices/self-hosting.md create mode 100644 .agents/skills/next-best-practices/suspense-boundaries.md create mode 100644 .agents/skills/vercel-react-best-practices/AGENTS.md create mode 100644 .agents/skills/vercel-react-best-practices/README.md create mode 100644 .agents/skills/vercel-react-best-practices/SKILL.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/_sections.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/_template.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/advanced-effect-event-deps.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/advanced-init-once.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/async-api-routes.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/async-cheap-condition-before-await.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/async-defer-await.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/async-dependencies.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/async-parallel.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/bundle-analyzable-paths.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/bundle-conditional.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/bundle-preload.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/client-event-listeners.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/js-cache-storage.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/js-early-exit.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/js-flatmap-filter.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/js-index-maps.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/js-length-check-first.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/js-request-idle-callback.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rendering-activity.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rendering-resource-hints.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-memo.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-transitions.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/server-auth-actions.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/server-cache-lru.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/server-cache-react.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/server-dedup-props.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/server-hoist-static-io.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/server-no-shared-module-state.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/server-parallel-nested-fetching.md create mode 100644 .agents/skills/vercel-react-best-practices/rules/server-serialization.md create mode 100644 .claude/settings.json create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/.agents/skills/next-best-practices/SKILL.md b/.agents/skills/next-best-practices/SKILL.md new file mode 100644 index 00000000..437896b4 --- /dev/null +++ b/.agents/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/.agents/skills/next-best-practices/async-patterns.md b/.agents/skills/next-best-practices/async-patterns.md new file mode 100644 index 00000000..dce8d8cc --- /dev/null +++ b/.agents/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/.agents/skills/next-best-practices/bundling.md b/.agents/skills/next-best-practices/bundling.md new file mode 100644 index 00000000..ac5e814c --- /dev/null +++ b/.agents/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 | +|---------|-------|-----| +| `