문서
App Router 사용하기
컴포넌트
<Script>

<Script>

이 API 참조는 Script 컴포넌트에 사용 가능한 props를 이해하는 데 도움이 될 것입니다. 기능과 사용법에 대해서는 스크립트 최적화 페이지를 참조하세요.

app/dashboard/page.tsx
import Script from "next/script";
 
export default function Dashboard() {
  return (
    <>
      <Script src="https://example.com/script.js" />
    </>
  );
}
app/dashboard/page.js
import Script from "next/script";
 
export default function Dashboard() {
  return (
    <>
      <Script src="https://example.com/script.js" />
    </>
  );
}

Props

Script 컴포넌트에 사용 가능한 props의 요약입니다:

Prop예시타입필수
srcsrc="http://example.com/script"String인라인 스크립트를 사용하지 않는 한 필수
strategystrategy="lazyOnload"String-
onLoadonLoad={onLoadFunc}Function-
onReadyonReady={onReadyFunc}Function-
onErroronError={onErrorFunc}Function-

필수 Props

<Script /> 컴포넌트는 다음 속성을 필요로 합니다.

src

외부 스크립트의 URL을 지정하는 경로 문자열입니다. 이는 절대 외부 URL이거나 내부 경로일 수 있습니다. 인라인 스크립트를 사용하지 않는 한 src 속성은 필수입니다.

선택적 Props

<Script /> 컴포넌트는 필수 속성 외에도 여러 추가 속성을 받아들입니다.

strategy

스크립트의 로딩 전략입니다. 네 가지 다른 전략을 사용할 수 있습니다:

  • beforeInteractive: 모든 Next.js 코드와 페이지 하이드레이션 전에 로드합니다.
  • afterInteractive: (기본값) 페이지에서 일부 하이드레이션이 발생한 후 일찍 로드합니다.
  • lazyOnload: 브라우저 유휴 시간 동안 로드합니다.
  • worker: (실험적) 웹 워커에서 로드합니다.

beforeInteractive

beforeInteractive 전략으로 로드되는 스크립트는 서버로부터의 초기 HTML에 삽입되어, 모든 Next.js 모듈 전에 다운로드되며, 페이지에서 어떤 하이드레이션이 발생하기 전에 순서대로 실행됩니다.

이 전략으로 표시된 스크립트는 모든 퍼스트파티 코드 전에 미리 로드되고 가져오지만, 그 실행은 페이지 하이드레이션을 차단하지 않습니다.

beforeInteractive 스크립트는 반드시 루트 레이아웃(app/layout.tsx) 내에 배치되어야 하며, 전체 사이트에 필요한 스크립트를 로드하도록 설계되었습니다(즉, 애플리케이션의 어떤 페이지가 서버 사이드에서 로드되었을 때 스크립트가 로드됩니다).

이 전략은 페이지의 어떤 부분이 상호작용 가능해지기 전에 가져와야 하는 중요한 스크립트에만 사용해야 합니다.

app/layout.tsx
import Script from "next/script";
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script
          src="https://example.com/script.js"
          strategy="beforeInteractive"
        />
      </body>
    </html>
  );
}
app/layout.js
import Script from "next/script";
 
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script
          src="https://example.com/script.js"
          strategy="beforeInteractive"
        />
      </body>
    </html>
  );
}

알아두면 좋은 점: beforeInteractive를 사용하는 스크립트는 컴포넌트 내 어디에 배치되었는지와 상관없이 항상 HTML 문서의 head 내부에 삽입됩니다.

beforeInteractive로 가능한 한 빨리 로드해야 하는 스크립트의 몇 가지 예시:

  • 봇 탐지기
  • 쿠키 동의 관리자

afterInteractive

afterInteractive 전략을 사용하는 스크립트는 클라이언트 사이드 HTML에 삽입되며 페이지에서 일부(또는 모든) 하이드레이션이 발생한 후에 로드됩니다. 이는 Script 컴포넌트의 기본 전략이며 가능한 한 빨리 로드해야 하지만 퍼스트파티 Next.js 코드 전에는 로드할 필요가 없는 모든 스크립트에 사용해야 합니다.

afterInteractive 스크립트는 모든 페이지나 레이아웃 내에 배치할 수 있으며, 해당 페이지(또는 페이지 그룹)가 브라우저에서 열렸을 때만 로드되고 실행됩니다.

app/page.js
import Script from "next/script";
 
export default function Page() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="afterInteractive" />
    </>
  );
}

afterInteractive에 적합한 스크립트의 몇 가지 예시:

  • 태그 매니저
  • 애널리틱스

lazyOnload

lazyOnload 전략을 사용하는 스크립트는 클라이언트 사이드 HTML에 삽입되며 브라우저 유휴 시간 동안 페이지의 모든 리소스가 가져와진 후에 로드됩니다. 이 전략은 일찍 로드할 필요가 없는 모든 백그라운드 또는 낮은 우선순위 스크립트에 사용해야 합니다.

lazyOnload 스크립트는 모든 페이지나 레이아웃 내에 배치할 수 있으며, 해당 페이지(또는 페이지 그룹)가 브라우저에서 열렸을 때만 로드되고 실행됩니다.

app/page.js
import Script from "next/script";
 
export default function Page() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="lazyOnload" />
    </>
  );
}

즉시 로드할 필요가 없고 lazyOnload로 가져올 수 있는 스크립트의 예시:

  • 채팅 지원 플러그인
  • 소셜 미디어 위젯

worker

경고: worker 전략은 아직 안정적이지 않으며 app 디렉토리에서는 아직 작동하지 않습니다. 주의해서 사용하세요.

worker 전략을 사용하는 스크립트는 메인 스레드를 해제하고 중요한 퍼스트파티 리소스만 메인 스레드에서 처리되도록 하기 위해 웹 워커로 오프로드됩니다. 이 전략은 모든 스크립트에 사용할 수 있지만, 모든 서드파티 스크립트를 지원하는 것이 보장되지 않는 고급 사용 사례입니다.

worker를 전략으로 사용하려면 next.config.js에서 nextScriptWorkers 플래그를 활성화해야 합니다:

next.config.js
module.exports = {
  experimental: {
    nextScriptWorkers: true,
  },
};

worker 스크립트는 현재 pages/ 디렉토리에서만 사용할 수 있습니다:

pages/home.tsx
import Script from "next/script";
 
export default function Home() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="worker" />
    </>
  );
}
pages/home.js
import Script from "next/script";
 
export default function Home() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="worker" />
    </>
  );
}

onLoad

경고: onLoad는 아직 서버 컴포넌트에서 작동하지 않으며 클라이언트 컴포넌트에서만 사용할 수 있습니다. 또한, onLoadbeforeInteractive와 함께 사용할 수 없습니다 - 대신 onReady를 사용하는 것을 고려해보세요.

일부 서드파티 스크립트는 스크립트 로딩이 완료된 후 콘텐츠를 인스턴스화하거나 함수를 호출하기 위해 JavaScript 코드를 한 번 실행해야 합니다. afterInteractive 또는 lazyOnload를 로딩 전략으로 사용하여 스크립트를 로드하는 경우, onLoad 속성을 사용하여 스크립트가 로드된 후 코드를 실행할 수 있습니다.

다음은 라이브러리가 로드된 후에만 lodash 메서드를 실행하는 예시입니다.

app/page.tsx
"use client";
 
import Script from "next/script";
 
export default function Page() {
  return (
    <>
      <Script
        src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"
        onLoad={() => {
          console.log(_.sample([1, 2, 3, 4]));
        }}
      />
    </>
  );
}
app/page.js
"use client";
 
import Script from "next/script";
 
export default function Page() {
  return (
    <>
      <Script
        src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"
        onLoad={() => {
          console.log(_.sample([1, 2, 3, 4]));
        }}
      />
    </>
  );
}

onReady

경고: onReady는 아직 서버 컴포넌트에서 작동하지 않으며 클라이언트 컴포넌트에서만 사용할 수 있습니다.

일부 서드파티 스크립트는 스크립트가 로딩을 완료한 후와 컴포넌트가 마운트될 때마다(예: 라우트 네비게이션 후) JavaScript 코드를 실행해야 합니다. onReady 속성을 사용하여 스크립트가 처음 로드될 때 스크립트의 로드 이벤트 후에 코드를 실행하고, 이후 모든 컴포넌트 재마운트 후에도 코드를 실행할 수 있습니다.

다음은 컴포넌트가 마운트될 때마다 Google Maps JS 내장 요소를 재구성하는 예시입니다:

app/page.tsx
"use client";
 
import { useRef } from "react";
import Script from "next/script";
 
export default function Page() {
  const mapRef = useRef();
 
  return (
    <>
      <div ref={mapRef}></div>
      <Script
        id="google-maps"
        src="https://maps.googleapis.com/maps/api/js"
        onReady={() => {
          new google.maps.Map(mapRef.current, {
            center: { lat: -34.397, lng: 150.644 },
            zoom: 8,
          });
        }}
      />
    </>
  );
}
app/page.js
"use client";
 
import { useRef } from "react";
import Script from "next/script";
 
export default function Page() {
  const mapRef = useRef();
 
  return (
    <>
      <div ref={mapRef}></div>
      <Script
        id="google-maps"
        src="https://maps.googleapis.com/maps/api/js"
        onReady={() => {
          new google.maps.Map(mapRef.current, {
            center: { lat: -34.397, lng: 150.644 },
            zoom: 8,
          });
        }}
      />
    </>
  );
}

onError

경고: onError는 아직 서버 컴포넌트에서 작동하지 않으며 클라이언트 컴포넌트에서만 사용할 수 있습니다. onErrorbeforeInteractive 로딩 전략과 함께 사용할 수 없습니다.

때로는 스크립트 로딩 실패를 감지하는 것이 도움이 됩니다. 이러한 오류는 onError 속성으로 처리할 수 있습니다:

app/page.tsx
"use client";
 
import Script from "next/script";
 
export default function Page() {
  return (
    <>
      <Script
        src="https://example.com/script.js"
        onError={(e: Error) => {
          console.error("스크립트 로딩 실패", e);
        }}
      />
    </>
  );
}
app/page.js
"use client";
 
import Script from "next/script";
 
export default function Page() {
  return (
    <>
      <Script
        src="https://example.com/script.js"
        onError={(e: Error) => {
          console.error("스크립트 로딩 실패", e);
        }}
      />
    </>
  );
}

버전 히스토리

버전변경 사항
v13.0.0beforeInteractiveafterInteractiveapp을 지원하도록 수정되었습니다.
v12.2.4onReady prop이 추가되었습니다.
v12.2.2beforeInteractive를 사용하는 next/script_document에 배치할 수 있게 되었습니다.
v11.0.0next/script가 도입되었습니다.