Script 컴포넌트 사용법
이번 글에서는 Next.js에서 제공하는 Script
컴포넌트에 대해 알아볼게요. Script
컴포넌트는 외부 스크립트를 페이지에 쉽게 로드하고, 로딩 시점이나 우선순위 등을 조절할 수 있어서 성능 최적화에 정말 유용합니다. 더 자세한 기능과 사용법은 Next.js 공식 문서의 Optimizing Scripts 페이지를 참고해보세요.
import Script from 'next/script'
export default function Dashboard() {
return (
<>
<Script src="https://example.com/script.js" />
</>
)
}
위 예시는 가장 기본적인 사용법으로, 외부 스크립트 URL을 src
속성으로 전달해 페이지에 적용하는 모습입니다.
Script 컴포넌트 주요 Props
아래 표에선 Script 컴포넌트에서 자주 사용하는 props를 정리해봤어요. 각 속성은 스크립트 로딩 시점, 실행 방식 등을 제어하는 데 도움을 줍니다.
Prop | 타입 | 설명 | 기본값 |
---|---|---|---|
src | string | 로드할 외부 스크립트의 URL | (필수) |
strategy | 'beforeInteractive' | 'afterInteractive' | 'lazyOnload' | 스크립트 로딩 전략. beforeInteractive 는 HTML 파싱 전에, afterInteractive 는 페이지가 상호작용 가능해진 후, lazyOnload 는 브라우저가 유휴 상태일 때 로드합니다. | 'afterInteractive' |
onLoad | function | 스크립트가 정상적으로 로드됐을 때 호출되는 콜백 | - |
onError | function | 스크립트 로딩에 실패했을 때 호출되는 콜백 | - |
id | string | 스크립트 엘리먼트의 고유 식별자 | - |
dangerouslySetInnerHTML | { __html: string } | 스크립트 내부에 직접 코드를 삽입할 때 사용 | - |
전략(strategy)에 대해 조금 더 설명하자면
-
beforeInteractive
페이지가 사용자와 상호작용하기 전에 스크립트를 미리 로드해야 할 때 사용합니다. 예를 들어, 핵심 기능을 담당하는 라이브러리라면 이 전략이 적합할 수 있어요. -
afterInteractive
메인 콘텐츠가 준비된 후에 스크립트를 로드합니다. 보통 기본값으로 사용되며, 사용자 경험에 큰 영향을 주지 않으면서 추가 스크립트를 로드하고 싶을 때 좋아요. -
lazyOnload
페이지가 완전히 로딩된 뒤, 브라우저가 한가할 때 스크립트를 로드하는 아주 느긋한 방법입니다. 성능 최적화에 매우 유용하지만, 즉시 필요한 스크립트에는 사용하지 않는 게 좋습니다.
직접 내부 코드를 넣고 싶을 때
<Script
id="show-banner"
dangerouslySetInnerHTML={{
__html: `
alert('Welcome to our site!');
`,
}}
/>
이렇게 하면 별도로 스크립트 파일을 만들지 않고도 페이지에 간단한 자바스크립트 코드를 삽입할 수 있죠. 단, XSS 공격 방지를 위해 내용에 주의를 기울여야 합니다.
Script
컴포넌트는 외부 스크립트 로딩을 제어하면서도 Next.js의 서버 사이드 렌더링(SSR) 환경에 잘 맞게 설계됐다 보니, 꼭 알아두면 프로젝트 성능 관리에 큰 도움이 될 거예요. 다음에는 더 다양한 예제와 활용 방법도 공유할게요!
Script 컴포넌트에서 사용할 수 있는 props를 간단히 정리해봤어요.
Prop | Example | Type | Required |
---|---|---|---|
src | src="http://example.com/script" | String | inline 스크립트를 사용하지 않는 한 필수입니다. |
strategy | strategy="lazyOnload" | String | 선택사항입니다. |
onLoad | onLoad={onLoadFunc} | Function | 선택사항입니다. |
onReady | onReady={onReadyFunc} | Function | 선택사항입니다. |
onError | onError={onErrorFunc} | Function | 선택사항입니다. |
필수로 꼭 필요한 Prop
Script
컴포넌트를 사용할 때 기본적으로 꼭 지정해줘야 하는 prop은 src
입니다. 물론 인라인 스크립트를 사용하는 경우라면 src
없이도 가능해요.
src
는 외부에서 불러올 스크립트 파일의 URL을 지정하는 곳이에요.strategy
는 스크립트 로딩 시점을 제어하는 옵션인데, 성능 최적화를 원할 땐lazyOnload
같은 값을 주면 페이지 로딩 후에 느긋하게 불러옵니다.onLoad
,onReady
,onError
같은 콜백 함수들은 스크립트 로딩 상태를 감지해서 필요한 작업을 연결할 때 유용합니다. 예를 들어 서드파티 스크립트 로딩이 끝난 후에 어떤 함수를 실행하고 싶을 때 써보세요.
간단하지만 스크립트 로딩 관리에서 꽤 유용하게 쓰일 수 있으니, 적절히 활용해보면 좋아요! 궁금한 점 있으면 또 알려줄게요 :)
src
src
는 외부 스크립트의 URL 경로를 지정하는 문자열이에요. 이 경로는 절대 URL(예: https://example.com/script.js)일 수도 있고, 내부 경로나 상대 경로일 수도 있죠. 중요한 점은, 인라인(inline) 스크립트를 사용하지 않는 한 src
속성은 반드시 지정해줘야 한다는 거예요.
내가 한 가지 더 알려주자면, 외부 스크립트를 사용할 때는 CORS 정책이나 네트워크 지연 문제도 고려해야 해요. 만약 스크립트 로딩이 지연되면 페이지 렌더링에도 영향을 줄 수 있으니까, async
나 defer
같은 속성을 잘 활용해서 비동기 로딩을 하는 것도 추천합니다.
Optional Props
Script /
컴포넌트는 필수 속성 외에도 사용자가 편리하게 쓸 수 있도록 여러 추가 속성을 지원해요. 이 옵션들을 잘 활용하면 스크립트 로딩이나 실행 타이밍을 세밀하게 조절할 수 있어서 더욱 효율적이죠.
아래는 주요 옵션들입니다:
속성 이름 | 설명 |
---|---|
async | 스크립트를 비동기로 로드합니다. 페이지 렌더링을 차단하지 않아요. |
defer | DOM 파싱이 끝난 후 스크립트를 실행합니다. |
onLoad | 스크립트가 로드된 후 호출되는 콜백 함수입니다. |
onError | 로딩 에러가 발생했을 때 호출되는 콜백 함수입니다. |
strategy | 스크립트 로딩 전략을 지정합니다. (예: beforeInteractive , afterInteractive , lazyOnload ) |
여기서 strategy
속성은 Next.js 같은 프레임워크에서 제공하는 스크립트 최적화 옵션인데, 상황에 맞게 잘 선택하면 페이지 속도 최적화에 큰 도움이 됩니다.
필요하면 각각의 옵션에 대해서 더 자세히 알아보고, 상황에 맞게 조합해보세요. 스크립트 로딩이 잘 되어야 사용자 경험도 쾌적해진답니다!
strategy (스크립트 로딩 전략)
스크립트를 언제 어떻게 로딩할지 정하는 방법이에요. 총 4가지 방법이 있는데, 각각의 특징이 조금씩 달라요.
전략명 | 설명 |
---|---|
beforeInteractive | Next.js 코드 실행 전에, 그리고 페이지가 활성화되기 전에 미리 로딩해요. |
afterInteractive | (기본값) 페이지가 어느 정도 활성화된 후에 로딩하지만, 그래도 빠른 편이에요. |
lazyOnload | 브라우저가 한가할 때, 나중에 천천히 로딩해요. |
worker | (실험적) 웹 워커 안에서 로딩해요. 메인 스레드 부담을 줄여줍니다. |
beforeInteractive
beforeInteractive
전략은 말 그대로 페이지가 완전히 활성화되기 전에, Next.js의 어떤 코드보다도 먼저 스크립트를 로딩해요. 이걸 쓰는 이유는 페이지가 초기화되기 전에 꼭 필요한 스크립트가 있을 때인데요.
예를 들어, 페이지가 렌더링되는 순간 바로 동작해야 할 자바스크립트가 있거나, 어떤 중요 라이브러리(예: 전역 상태관리 라이브러리)가 빨리 준비돼야 할 경우에 좋습니다.
하지만 무조건 빨리 로딩한다고 좋은 건 아니에요! 이 전략을 남용하면 페이지 초기 로딩 속도가 느려질 수 있으니 꼭 필요한 경우에만 사용하는 게 좋아요.
Tip!
afterInteractive
가 기본값이라, 특별한 이유가 없다면 이걸 쓰는 게 무난합니다.- 만약 무거운 스크립트라면
lazyOnload
전략을 사용해서 사용자가 페이지를 충분히 볼 수 있을 때 로딩하는 게 좋습니다. - 웹 워커(
worker
전략)는 아직 실험 단계지만, 스크립트가 백그라운드에서 처리되어 메인 UI 렌더링 성능이 좋아질 수 있으니 관심 있으면 조금씩 써보세요!
Next.js에서 beforeInteractive
로드 전략을 사용하는 스크립트에 대해 이야기해볼게요.
beforeInteractive 로드 전략이란?
beforeInteractive
전략을 사용하면, 해당 스크립트가 서버에서 초기 HTML에 바로 주입돼요. 그러니까 브라우저가 Next.js의 어떤 모듈도 다운받기 전에, 이 스크립트부터 먼저 다운로드하고 실행하게 됩니다. 이게 무슨 의미일까요? 중요한 스크립트를 아주 빨리 불러오고 싶을 때 쓸 수 있다는 거죠.
하지만 여기서 중요한 점! 실행은 페이지 수화(page hydration)를 막지 않아요. 즉, 이 스크립트를 실행한다고 해서 React가 클라이언트에서 페이지를 활성화하는 과정을 지연시키지 않습니다.
어디에 위치해야 할까?
beforeInteractive
스크립트는 루트 레이아웃(app/layout.tsx
) 안에 넣어야 합니다. 왜냐하면, 이 전략은 애플리케이션 어떤 페이지가 로드되더라도 반드시 필요한 공통 스크립트(예: 폰트 로더, 전역 추적 코드 등)를 로드하게 설계되어 있기 때문입니다.
사용하면 좋은 경우
이 전략은 진짜 필수적인 스크립트에만 쓰는 게 좋아요. 예를 들어,
- 전체 사이트에 적용되는 폰트 로딩 스크립트
- 필수적인 애널리틱스 코드
- 크리티컬 CSS나 자바스크립트 초기화 스크립트
이런 것들이에요. 너무 많아지면 페이지 로딩 초기 비용이 커질 수 있으니 주의!
간단 정리 (Markdown 표)
특징 | 설명 |
---|---|
주입 위치 | 서버에서 초기 HTML에 직접 삽입 |
다운로드 시점 | Next.js 모듈보다 먼저 다운로드 |
실행 순서 | 삽입된 순서대로 실행 |
페이지 수화 차단 여부 | 실행해도 페이지 수화 과정(block)에는 영향 없음 |
배치 위치 | app/layout.tsx (루트 레이아웃) |
주 용도 | 전체 사이트에 필요한 필수 스크립트 즉시 로드 |
덧붙여서
실제로 프로젝트에서 이걸 설정하려면, <Script>
컴포넌트를 이렇게 쓰면 됩니다.
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html>
<head>
<Script src="/critical-script.js" strategy="beforeInteractive" />
</head>
<body>{children}</body>
</html>
);
}
이렇게 하면 /critical-script.js
가 Next.js 모듈보다 먼저 다운로드되고 실행돼서, 사이트 구동에 꼭 필요한 스크립트를 미리 준비할 수 있어요.
요약하자면, beforeInteractive
는 “진짜 꼭 필요한 아주 중요한 스크립트를 최대한 빨리, 페이지 수화 지연 없이 불러올 때” 사용하는 로드 전략입니다.
필요에 따라 맞춤형으로 활용해보세요!
Next.js에서 <Script>
컴포넌트를 사용할 때 strategy="beforeInteractive"
옵션을 자주 보게 되는데요, 이 옵션이 어떤 역할을 하는지 간단히 알려드릴게요!
위 코드를 보면, <Script>
태그가 <body>
안에 있지만 사실상 beforeInteractive
로 설정된 스크립트는 항상 HTML 문서의 <head>
안에 주입됩니다. 즉, 컴포넌트 내부 어디에 두든지 페이지가 렌더링 되기 전에 스크립트가 로드된다는 뜻이에요.
왜 이게 중요하냐면, 페이지가 사용자와 상호작용하기 전에 꼭 필요한 스크립트들이 미리 로드되어 있어야 하기 때문입니다. 예를 들어:
예시 스크립트 종류 | 설명 |
---|---|
봇 탐지(bot detectors) | 크롤러나 봇을 빠르게 식별하려면 초기 단계에서 실행 필요 |
쿠키 동의 관리(cookie consent managers) | 개인정보 동의 팝업이나 관리 스크립트는 인터랙션 전에 준비되어야 함 |
이런 스크립트들은 사용자의 상호작용이 일어나기 전부터 로드되어서 빠르게 동작해야 하므로 beforeInteractive
전략을 써서 우선순위를 높여주는 게 좋은 방법입니다.
추가로 알아두면 좋은 점!
beforeInteractive
외에도lazyOnload
,afterInteractive
같은 전략이 있는데, 각각 로드 시점과 우선순위가 다르니 상황에 맞게 선택해야 합니다.- 그리고 Next.js는 스크립트 최적화에 신경을 많이 썼기 때문에, 직접
<script>
태그를 쓰기보다는<Script>
컴포넌트를 활용하는 걸 추천해요. 그래야 스크립트 로딩 타이밍과 위치를 자동으로 제어해줘서 성능과 SEO에 도움됩니다.
간단하게 정리하자면, 꼭 페이지가 사용자와 상호작용하기 전에 필요한 스크립트가 있다면 strategy="beforeInteractive"
로 설정해주면 좋다!고 이해하시면 됩니다.
필요한 경우 저도 자주 쓰는 옵션이라, 다음에 스크립트 로딩 전략에 대해 더 자세히 공유해볼게요. :)
afterInteractive 전략이란?
Next.js에서 Script
컴포넌트를 사용할 때 strategy="afterInteractive"
옵션을 자주 보게 되실 텐데요. 이건 스크립트를 클라이언트 쪽에 삽입하고, 페이지가 렌더링된 후에 실행하도록 하는 방식이에요. 쉽게 말해, Next.js가 페이지를 초기화하고, 클라이언트에서 인터랙티브 상태가 된 다음에 스크립트를 로딩하는 거죠.
보통 이 전략은 기본값이기도 하고, 첫 번째로 실행해야 하는 Next.js 내부 코드가 끝난 다음 바로 실행돼야 하는 스크립트에 사용돼요. 예를 들어, 외부 광고 스크립트나 사용자 행동 추적 스크립트 같은 게 이에 해당됩니다.
특징
- 원하는 페이지나 레이아웃 어디에든 넣을 수 있어요.
- 해당 페이지가 클라이언트에서 접근될 때만 로드되고 실행됩니다.
- 페이지 로딩 속도를 어느 정도 지키면서 외부 스크립트를 넣고 싶을 때 적합합니다.
아래는 실제 사용 예제인데, strategy="afterInteractive"
를 명시하지 않아도 기본값이라서 생략 가능해요.
import Script from 'next/script'
export default function Page() {
return (
<>
<Script src="https://example.com/script.js" strategy="afterInteractive" />
</>
)
}
추가로 알아두면 좋은 점!
afterInteractive
말고도 Next.js는beforeInteractive
,lazyOnload
같은 다양한 로딩 전략이 있어요. 각각 특성이 달라서 상황에 맞게 골라서 사용하면 됩니다.- 만약 빠른 우선 실행이 필요한 스크립트면
beforeInteractive
를, 페이지가 완전히 로드된 후 실행하면 충분한 스크립트는lazyOnload
를 쓰는 식이죠. - 이 전략을 잘 활용하면, 사용자 경험을 해치지 않으면서도 사이트에 꼭 필요한 외부 스크립트들을 최적화할 수 있습니다.
Next.js에서 스크립트 로딩 전략을 이해하고 사용하면 성능과 UX 모두 챙길 수 있으니, 꼭 한 번 실습해 보시길 추천드려요!
afterInteractive에 적합한 스크립트 예시로는 다음과 같은 것들이 있어요!
- 태그 매니저 (Tag managers)
- 애널리틱스 (Analytics)
lazyOnload
lazyOnload 전략을 사용하는 스크립트는 브라우저가 한가한 시간(Idle time)에 클라이언트 쪽 HTML에 주입돼요. 페이지의 모든 리소스가 다 로드된 후에 실행되기 때문에, 초반에 빠르게 로드할 필요가 없는 백그라운드 작업이나 우선 순위가 낮은 스크립트에 딱 맞아요.
즉, 예를 들어 사용자 경험에 큰 영향을 미치지 않는 광고 트래킹 코드나 추가적인 위젯 스크립트 등은 lazyOnload로 관리하면 초기 페이지 로딩 속도를 잡아주는 데 도움이 된답니다.
이렇게 스크립트의 로딩 전략을 상황에 맞게 골라주면 페이지 퍼포먼스 최적화에 큰 도움이 되니 꼭 참고해보세요!
next.js에서 제공하는 <Script>
컴포넌트의 lazyOnload
전략에 대해 이야기해볼게요.
이 lazyOnload
옵션은 스크립트를 페이지나 레이아웃 어디에든 넣을 수 있는데, 실제로 그 페이지(또는 해당 그룹의 페이지)가 브라우저에서 열릴 때 스크립트가 로드되고 실행돼요. 즉, 페이지가 처음 렌더링될 때 바로 로드할 필요가 없는 스크립트를 뒤로 미루는 셈이죠.
import Script from 'next/script'
export default function Page() {
return (
<>
<Script src="https://example.com/script.js" strategy="lazyOnload" />
</>
)
}
예를 들어, 아래와 같은 경우 lazyOnload
로 스크립트를 불러오면 좋아요:
- 채팅 지원 플러그인 (Chat support plugins)
- SNS 위젯 (Social media widgets)
왜냐하면 이런 스크립트들은 페이지가 뜨자마자 바로 작동할 필요는 없고, 사용자 경험에 큰 영향을 주지 않으면서도 필요할 때 로딩되면 충분하기 때문이에요.
추가 팁!
lazyOnload
는 기본 afterInteractive
전략보다도 늦게 실행되기 때문에 초기 페이지 렌더링에 거의 영향을 주지 않아요. 하지만 꼭 필요한 스크립트여서 사용자 즉각 반응에 영향을 미친다면, 오히려 afterInteractive
를 사용하는 것이 좋답니다.
그리고 혹시 페이지가 복잡해서 스크립트가 많아지면, 지연 로드 전략을 잘 활용하는 게 사용자 퍼포먼스 측면에서 완전 도움이 되니 꼭 기억해둬요!
worker 전략 사용하기
경고: worker 전략은 아직 안정화 단계가 아니며 App Router와는 아직 호환되지 않습니다. 사용 시 주의가 필요해요.
worker 전략은 스크립트를 웹 워커(Web Worker)로 분리해서 메인 스레드가 여유로워지도록 도와줍니다. 이렇게 하면 주요한 첫 번째 파티 리소스들만 메인 스레드에서 처리되고, 나머지 스크립트는 워커에서 실행되기 때문에 성능에 긍정적인 영향을 줄 수 있죠.
하지만 이 전략은 아직 조금 고급 사용법에 속하고, 모든 타사 스크립트를 지원하지 않을 수 있다는 걸 기억하세요. 적절한 테스트가 필요해요.
만약 worker 전략을 사용하고 싶다면, next.config.js 파일 안에 nextScriptWorkers
플래그를 활성화해야 합니다:
// next.config.js
module.exports = {
experimental: {
nextScriptWorkers: true,
},
};
이렇게 설정하면 스크립트가 워커 쪽에서 실행될 수 있도록 준비됩니다.
참고로, 웹 워커를 사용하면 복잡한 연산이나 무거운 스크립트가 메인 스레드를 막는 현상을 줄여줄 수 있어서 사용자 경험(UX) 향상에 큰 도움이 돼요. 하지만 모든 코드가 워커 환경에 맞는 것은 아니고, DOM에 직접 접근하는 코드는 워커에서 불가능하니 워커로 옮길 때는 이 점도 신경 써야 해요.
추가적으로, 워커를 제대로 활용하면 페이지 응답 속도 개선은 물론이고, UI가 멈추는 현상(jank)도 크게 줄일 수 있어서 성능 최적화에 관심 있다면 충분히 고려해볼 만한 전략입니다.
이번에는 Next.js에서 제공하는 nextScriptWorkers
실험 기능과 worker
전략을 사용하는 방법에 대해 알아볼게요. 이 기능을 활용하면 스크립트를 워커(worker)로 실행해서 메인 스레드의 부담을 줄일 수 있어요. 하지만 아직은 실험 단계라서, 사용법에 몇 가지 제약이 있답니다.
1. 설정 방법
먼저 next.config.js
에 다음과 같이 설정을 추가해 주세요.
module.exports = {
experimental: {
nextScriptWorkers: true,
},
}
이렇게 하면 Next.js가 스크립트를 웹 워커로 실행하는 걸 지원하게 됩니다.
2. 스크립트 사용 위치 제한
중요! 워커 스크립트는 현재 페이지 컴포넌트가 위치한 pages/
디렉터리 안에서만 사용할 수 있어요. 그래서 App
이나 Document
같은 전역 컴포넌트에서는 워커 전략을 사용할 수 없습니다.
3. 사용 예시
pages/index.js
같은 페이지에서 아래처럼 next/script
의 Script
컴포넌트를 쓰면서 strategy="worker"
를 넣으면 스크립트가 워커로 로드돼요.
import Script from 'next/script'
export default function Home() {
return (
<>
<Script src="https://example.com/script.js" strategy="worker" />
</>
)
}
4. onLoad 이벤트
Script
컴포넌트는 onLoad
프로퍼티를 지원해서 스크립트가 성공적으로 로드됐을 때 콜백을 실행할 수 있어요.
<Script
src="https://example.com/script.js"
strategy="worker"
onLoad={() => {
console.log('Worker script loaded!');
}}
/>
워커 안에서 실행되는 스크립트는 메인 스레드와는 별개라 직접적인 DOM조작이나 전역 변수 사용이 제한돼요. 그러니까 워커 쪽 스크립트는 주로 데이터 처리나 계산 같은 무거운 작업에 활용하는 게 좋아요.
5. 추가 팁
- 워커 스크립트에서 메인 스레드와 통신할 때는
postMessage
API를 사용하셔야 해요. - 아직 실험 기능이라서 Next.js 공식 문서나 GitHub 이슈 페이지에서 최신 상태를 참고하는 게 좋아요.
- 자주 변경될 수 있으니 프로덕션 환경에서는 신중히 사용하세요!
웹 워커를 활용하면 UI가 막히지 않고 부드럽게 동작하게 만들어주는 훌륭한 방법입니다. Next.js에서 실험적으로 지원하는 이 기능을 한번 사용해보고 퍼포먼스 향상에 도움이 되는지 직접 체험해보세요!
여러분, Next.js에서 <Script>
컴포넌트를 쓸 때 알아둬야 할 중요한 점이 있어요.
경고!
onLoad
이벤트 핸들러는 아직 서버 컴포넌트(Server Components)에서는 작동하지 않고 클라이언트 컴포넌트(Client Components)에서만 쓸 수 있어요. 또,beforeInteractive
로딩 전략과는 함께 못 쓰니까onReady
를 대신 사용하는 게 좋아요.
왜 이런 얘기를 하냐면, 가끔 우리가 외부 서드파티 스크립트를 로드할 때 스크립트가 다 로딩된 후에 특정 함수를 실행해야 할 때가 있잖아요. 그런 경우에 afterInteractive
나 lazyOnload
같은 로딩 전략으로 스크립트를 불러온 다음, onLoad
프로퍼티를 활용하면 원하는 작업을 안전하게 실행할 수 있답니다.
간단한 예를 들어볼게요. lodash라는 유명한 유틸 라이브러리를 외부 CDN에서 불러오고, 로딩이 완료되면 lodash의 sample
메서드를 써서 배열에서 랜덤 값을 뽑아 콘솔에 찍는 코드예요.
'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]))
}}
strategy="afterInteractive" // 로딩 시점 지정도 잊지 말기
/>
</>
)
}
여기서 중요 포인트 정리!
내용 | 설명 |
---|---|
onLoad | 스크립트가 완전히 로드된 후 실행되는 함수 |
사용 가능 위치 | 클라이언트 컴포넌트 내에서만 사용 가능 |
로딩 전략 | beforeInteractive 와 함께 사용 불가, 대신 afterInteractive 추천 |
대안 | beforeInteractive 쓸 때는 onReady 속성 사용 |
이 방식을 이용하면 외부 스크립트가 준비된 이후에 바로 원하는 JS 코드를 실행할 수 있어서 효과적이에요.
만약 Next.js에서 서버 사이드 렌더링(SSR) 모드로 작업 중이라면, 클라이언트 컴포넌트에 'use client'
를 꼭 붙여줘야 onLoad
같은 클라이언트 전용 기능이 작동한다는 점도 꼭 기억하세요!
필요하다면 스크립트의 로딩 시점을 바꾸는 strategy
속성을 다양하게 조합해서 페이지 성능 최적화에 신경쓰면 더 좋겠죠? afterInteractive
는 페이지가 인터랙티브한 상태가 된 후, lazyOnload
는 브라우저가 한가해질 때 로드하는 등 상황에 맞춰 선택할 수 있어요.
이렇게 외부 스크립트와 우리 코드가 잘 협업하는 방법, 다음 프로젝트 때 유용하게 활용해보세요!
onReady
경고: onReady는 아직 Server Components에서는 작동하지 않고, Client Components에서만 사용할 수 있어요.
어떤 서드파티 스크립트들은 스크립트가 완전히 로드된 후, 그리고 컴포넌트가 마운트될 때마다 자바스크립트 코드를 실행해야 할 때가 있어요. 예를 들면, 페이지 경로가 바뀌어서 컴포넌트가 다시 렌더링될 때마다 말이죠.
이럴 때 onReady
속성을 활용하면, 스크립트가 처음 로드될 때뿐 아니라 매번 컴포넌트가 다시 마운트될 때마다 코드를 실행할 수 있어요.
예를 들어, 구글 맵을 컴포넌트가 마운트될 때마다 다시 불러와야 할 때 아래처럼 쓸 수 있답니다.
<Script
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"
onReady={() => {
// 컴포넌트가 마운트될 때마다 구글 맵 재초기화
const map = new window.google.maps.Map(document.getElementById("map"), {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
});
}}
/>
팁!
onReady는 스크립트가 완전히 로드된 시점과 컴포넌트가 재마운트되는 시점을 포괄해서 처리하기 때문에, 복잡한 외부 라이브러리 초기화 작업에 특히 유용해요.
다만, Server Components에서는 아직 지원하지 않으니, 클라이언트 전용 컴포넌트에서만 사용해야 한다는 거 꼭 기억하세요!
여러분, 리액트와 Next.js에서 구글 맵스(google maps) API를 불러오고 싶을 때 어떻게 하는지 아시나요? 위에 간단한 예제가 있는데요, next/script
컴포넌트를 이용해서 외부 스크립트를 쉽게 불러올 수 있습니다.
'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,
})
}}
/>
</>
)
}
여기서 mapRef
로 div 요소를 잡아두고, 구글 맵이 스크립트가 로드된 후에 new google.maps.Map
을 실행해서 지도를 띄우는 식입니다. 중요한 점은 'use client'
를 꼭 붙여서 이 컴포넌트가 클라이언트 사이드에서만 동작하도록 만들어야 한다는 거예요. 구글 맵 API는 브라우저 환경에서 동작하기 때문에 서버 사이드에선 의미가 없거든요.
onError 옵션으로 에러 잡기
그리고 next/script
에는 onReady
뿐만 아니라 onError
라는 옵션도 있어요. 스크립트가 정상적으로 로드되지 않았을 때 에러를 잡아서 대처하기 편리하죠.
예를 들어,
<Script
id="google-maps"
src="https://maps.googleapis.com/maps/api/js"
onReady={() => {
// 정상 로드 시 초기화 코드
}}
onError={(e) => {
console.error('구글 맵 스크립트 로드 실패!', e)
}}
/>
하지만 한 가지 주의할 점! onError
는 아직 서버 컴포넌트에서는 동작하지 않고, beforeInteractive
같은 특정 로딩 전략과도 호환되지 않아요. 따라서 클라이언트 컴포넌트에서만 잘 활용할 수 있다는 점을 기억하세요.
추가 팁: 구글 맵 API 키
실제 프로젝트에서는 구글 맵 API를 불러올 때 API 키를 함께 줘야 제대로 작동해요. URL에 key=YOUR_API_KEY
파라미터를 넣어줘야 합니다.
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"
API 키 없이 그냥 불러오면 제한되거나 작동하지 않을 수 있으니 꼭 발급받고 넣어주세요. 혹시 모르시는 분들을 위해 구글 클라우드 플랫폼에서 API 키 발급받는 법도 다음에 따로 다뤄볼게요!
요약하자면:
개념 | 설명 |
---|---|
next/script | Next.js에서 외부 스크립트를 쉽고 안전하게 불러올 수 있는 컴포넌트 |
onReady | 스크립트 로드 완료 후 실행할 콜백 함수 |
onError | 스크립트 로드 실패 시 에러 처리 가능 (클라이언트 컴포넌트 전용) |
useRef | 리액트에서 DOM 요소를 직접 참조하기 위한 훅 |
API 키 | 구글 맵 API 사용 시 필수, URL 파라미터로 넣어야 제대로 동작 |
이 정도면 구글 맵 API를 Next.js에서 어떻게 붙이는지 쉽게 감이 오지 않나요? 앞으로 다양한 외부 스크립트와 API도 이렇게 표현할 수 있으니 자주 써보면서 익혀보세요! 궁금한 점 있으면 댓글로 남겨주세요 :)
안녕하세요! 이번에는 Next.js에서 제공하는 <Script>
컴포넌트를 사용하는 방법에 대해서 살펴볼게요.
Next.js의 <Script>
컴포넌트
Next.js에서 외부 스크립트를 쉽게 불러오고 관리할 수 있게 도와주는 컴포넌트가 바로 next/script
의 <Script>
입니다. 기본적으로 HTML의 <script>
태그를 대체하면서, 스크립트 로딩 전략을 제어하거나 로딩 실패 시 에러 처리도 할 수 있는 편리한 기능들을 가지고 있죠.
'use client'
import Script from 'next/script'
export default function Page() {
return (
<>
<Script
src="https://example.com/script.js"
onError={(e: Error) => {
console.error('Script failed to load', e)
}}
/>
</>
)
}
위 코드를 보면, src
속성에 외부 스크립트 URL을 넣고, onError
prop을 통해 로드 실패 시 콘솔에 에러를 출력하도록 구현했습니다.
💡 참고:
'use client'
는 이 컴포넌트가 클라이언트 컴포넌트라는 걸 알려줘서, 브라우저에서만 스크립트가 실행되도록 해줍니다.
next/script
버전별 변경사항 히스토리
<Script>
컴포넌트도 Next.js 버전 업데이트에 따라 점점 기능이 좋아지고 안정적으로 변해왔는데요, 주요 버전 변경사항을 한눈에 정리해봤어요:
Version | Changes |
---|---|
v13.0.0 | beforeInteractive 와 afterInteractive 가 app 디렉터리 지원을 위해 수정됨 |
v12.2.4 | onReady prop 추가 |
v12.2.2 | beforeInteractive 옵션을 가진 <Script> 를 _document 에 배치 가능하게 변경 |
v11.0.0 | next/script 컴포넌트 도입 |
추가로 알아두면 좋은 팁!
-
로드 전략 제어:
<Script>
는strategy
라는 속성을 통해 스크립트가 언제 로드되고 실행될지 정할 수 있어요. 주요 값으로는beforeInteractive
(HTML 파싱 전에 로드),afterInteractive
(페이지 인터랙티브 후 로드),lazyOnload
(브라우저 유휴 상태에서 로드) 등이 있답니다. -
중복 로드 방지:
<Script>
는 같은src
를 가진 스크립트가 여러 곳에 있어도 중복으로 로드하지 않으니, 여러 컴포넌트에서 스크립트를 사용할 때도 걱정 없어요. -
직접적인 DOM 접근이 필요할 때: 가끔 외부 스크립트가 페이지 렌더링에 영향을 미치거나, DOM 요소를 직접 조작해야 할 때가 있어요. 이럴 때는
<Script>
컴포넌트를 적절히 사용해서 로딩 순서를 관리하면 좋은 성능을 기대할 수 있답니다.
요약하자면, Next.js 11버전부터 등장한 <Script>
컴포넌트 덕분에 외부 스크립트를 더 안전하고 효율적으로 관리할 수 있게 되었어요. 앞으로 외부 자바스크립트를 넣을 때는 직접 <script>
태그 쓰기보다 이걸 적극 활용해 보세요!
궁금한 점 있으면 언제든 댓글로 물어봐 주세요! 😊