sangwook yoo 3ac66feba2 chore: .agents/.claude 설정·CLAUDE.md·AGENTS.md git 추적 추가
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) <noreply@anthropic.com>
2026-05-12 18:05:03 +09:00

3.2 KiB

Scripts

Loading third-party scripts in Next.js.

Use next/script

Always use next/script instead of native <script> tags for better performance.

// Bad: Native script tag
<script src="https://example.com/script.js"></script>

// Good: Next.js Script component
import Script from 'next/script'

<Script src="https://example.com/script.js" />

Inline Scripts Need ID

Inline scripts require an id attribute for Next.js to track them.

// Bad: Missing id
<Script dangerouslySetInnerHTML={{ __html: 'console.log("hi")' }} />

// Good: Has id
<Script id="my-script" dangerouslySetInnerHTML={{ __html: 'console.log("hi")' }} />

// Good: Inline with id
<Script id="show-banner">
  {`document.getElementById('banner').classList.remove('hidden')`}
</Script>

Don't Put Script in Head

next/script should not be placed inside next/head. It handles its own positioning.

// Bad: Script inside Head
import Head from 'next/head'
import Script from 'next/script'

<Head>
  <Script src="/analytics.js" />
</Head>

// Good: Script outside Head
<Head>
  <title>Page</title>
</Head>
<Script src="/analytics.js" />

Loading Strategies

// afterInteractive (default) - Load after page is interactive
<Script src="/analytics.js" strategy="afterInteractive" />

// lazyOnload - Load during idle time
<Script src="/widget.js" strategy="lazyOnload" />

// beforeInteractive - Load before page is interactive (use sparingly)
// Only works in app/layout.tsx or pages/_document.js
<Script src="/critical.js" strategy="beforeInteractive" />

// worker - Load in web worker (experimental)
<Script src="/heavy.js" strategy="worker" />

Google Analytics

Use @next/third-parties instead of inline GA scripts.

// Bad: Inline GA script
<Script src="https://www.googletagmanager.com/gtag/js?id=G-XXXXX" />
<Script id="ga-init">
  {`window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
    gtag('config', 'G-XXXXX');`}
</Script>

// Good: Next.js component
import { GoogleAnalytics } from '@next/third-parties/google'

export default function Layout({ children }) {
  return (
    <html>
      <body>{children}</body>
      <GoogleAnalytics gaId="G-XXXXX" />
    </html>
  )
}

Google Tag Manager

import { GoogleTagManager } from '@next/third-parties/google'

export default function Layout({ children }) {
  return (
    <html>
      <GoogleTagManager gtmId="GTM-XXXXX" />
      <body>{children}</body>
    </html>
  )
}

Other Third-Party Scripts

// YouTube embed
import { YouTubeEmbed } from '@next/third-parties/google'

<YouTubeEmbed videoid="dQw4w9WgXcQ" />

// Google Maps
import { GoogleMapsEmbed } from '@next/third-parties/google'

<GoogleMapsEmbed
  apiKey="YOUR_API_KEY"
  mode="place"
  q="Brooklyn+Bridge,New+York,NY"
/>

Quick Reference

Pattern Issue Fix
<script src="..."> No optimization Use next/script
<Script> without id Can't track inline scripts Add id attribute
<Script> inside <Head> Wrong placement Move outside Head
Inline GA/GTM scripts No optimization Use @next/third-parties
strategy="beforeInteractive" outside layout Won't work Only use in root layout