<script>

김동현·2026년 3월 17일

<script>

소개

브라우저 내장 <script> 컴포넌트를 사용하면 문서에 스크립트를 추가할 수 있어요.

<script> alert("hi!") </script>

레퍼런스

<script>

문서에 인라인 또는 외부 스크립트를 추가하려면, 브라우저 내장 <script> 컴포넌트를 렌더링하면 돼요. 어떤 컴포넌트에서든 <script>를 렌더링할 수 있고, React는 특정 경우에 해당 DOM 엘리먼트를 문서의 head에 배치하고 동일한 스크립트를 중복 제거해줄 거예요.

<script> alert("hi!") </script>
<script src="script.js" />

아래에서 더 많은 예제를 확인하세요.

Props

<script>는 모든 공통 엘리먼트 props를 지원해요.

children 또는 src prop 중 하나를 가져야 해요.

  • children: 문자열이에요. 인라인 스크립트의 소스 코드예요.
  • src: 문자열이에요. 외부 스크립트의 URL이에요.

기타 지원되는 props:

  • async: 불리언이에요. 브라우저가 나머지 문서가 처리될 때까지 스크립트 실행을 지연시킬 수 있게 해줘요 — 성능을 위해 권장되는 동작이에요.
  • crossOrigin: 문자열이에요. 사용할 CORS 정책이에요. 가능한 값은 anonymoususe-credentials예요.
  • fetchPriority: 문자열이에요. 여러 스크립트를 동시에 가져올 때 브라우저가 스크립트의 우선순위를 매길 수 있게 해줘요. "high", "low", 또는 "auto" (기본값)가 될 수 있어요.
  • integrity: 문자열이에요. 진위성을 확인하기 위한 스크립트의 암호화 해시예요.
  • noModule: 불리언이에요. ES 모듈을 지원하는 브라우저에서 스크립트를 비활성화해요 — 지원하지 않는 브라우저를 위한 폴백 스크립트를 허용하기 위해서예요.
  • nonce: 문자열이에요. 엄격한 Content Security Policy를 사용할 때 리소스를 허용하기 위한 암호화 nonce예요.
  • referrer: 문자열이에요. 스크립트를 가져올 때와 스크립트가 차례로 가져오는 모든 리소스를 가져올 때 어떤 Referer 헤더를 보낼지 말해줘요.
  • type: 문자열이에요. 스크립트가 클래식 스크립트인지, ES 모듈인지, import map인지 말해줘요.

React의 스크립트 특별 처리를 비활성화하는 props:

  • onError: 함수예요. 스크립트 로드에 실패했을 때 호출돼요.
  • onLoad: 함수예요. 스크립트 로드가 완료되었을 때 호출돼요.

React와 함께 사용하는 것이 권장되지 않는 props:

  • blocking: 문자열이에요. "render"로 설정하면, 스크립트시트가 로드될 때까지 브라우저가 페이지를 렌더링하지 않도록 지시해요. React는 Suspense를 사용해서 더 세밀한 제어를 제공해요.
  • defer: 문자열이에요. 문서 로딩이 완료될 때까지 브라우저가 스크립트를 실행하지 못하게 해요. 스트리밍 서버 렌더링 컴포넌트와 호환되지 않아요. 대신 async prop을 사용하세요.

💡 부연 설명: asyncdefer의 차이점이 헷갈릴 수 있어요!

  • async: 스크립트를 다운로드하는 동안 HTML 파싱을 계속하고, 다운로드가 완료되면 즉시 실행해요. 실행 순서가 보장되지 않아요.
  • defer: 스크립트를 다운로드하는 동안 HTML 파싱을 계속하고, HTML 파싱이 완료된 후에 순서대로 실행해요.

React에서는 async를 권장하는데, 이는 스트리밍 SSR과 더 잘 호환되기 때문이에요!

특별한 렌더링 동작

React는 <script> 컴포넌트를 문서의 <head>로 이동시키고 동일한 스크립트를 중복 제거할 수 있어요.

이 동작을 활성화하려면, srcasync={true} props를 제공하세요. React는 동일한 src를 가진 스크립트를 중복 제거할 거예요. async prop은 스크립트를 안전하게 이동시킬 수 있도록 반드시 true여야 해요.

이 특별한 처리에는 두 가지 주의사항이 있어요:

  • React는 스크립트가 렌더링된 후에는 props 변경을 무시해요. (개발 환경에서 이런 일이 발생하면 React가 경고를 표시할 거예요.)
  • React는 해당 스크립트를 렌더링한 컴포넌트가 언마운트된 후에도 DOM에 스크립트를 남겨둘 수 있어요. (스크립트는 DOM에 삽입될 때 한 번만 실행되기 때문에 이건 아무 영향도 없어요.)

사용법

외부 스크립트 렌더링하기

컴포넌트가 올바르게 표시되기 위해 특정 스크립트에 의존한다면, 컴포넌트 내에서 <script>를 렌더링할 수 있어요.
하지만, 스크립트 로딩이 완료되기 전에 컴포넌트가 커밋될 수 있어요.
load 이벤트가 발생한 후에 스크립트 내용에 의존하기 시작할 수 있어요. 예를 들어 onLoad prop을 사용해서요.

React는 동일한 src를 가진 스크립트를 중복 제거해서, 여러 컴포넌트가 렌더링하더라도 DOM에는 하나만 삽입해요.

// src/App.js
import ShowRenderedHTML from './ShowRenderedHTML.js';

function Map({lat, long}) {
  return (
    <>
      <script async src="map-api.js" onLoad={() => console.log('script loaded')} />
      <div id="map" data-lat={lat} data-long={long} />
    </>
  );
}

export default function Page() {
  return (
    <ShowRenderedHTML>
      <Map />
    </ShowRenderedHTML>
  );
}

📝 참고
스크립트를 사용하고 싶을 때, preinit 함수를 호출하는 것이 유익할 수 있어요. 이 함수를 호출하면 단순히 <script> 컴포넌트를 렌더링하는 것보다 브라우저가 스크립트를 더 일찍 가져오기 시작할 수 있어요. 예를 들어 HTTP Early Hints 응답을 보내는 방식으로요.

인라인 스크립트 렌더링하기

인라인 스크립트를 포함하려면, 스크립트 소스 코드를 children으로 가진 <script> 컴포넌트를 렌더링하세요. 인라인 스크립트는 중복 제거되거나 문서 <head>로 이동되지 않아요.

// src/App.js
import ShowRenderedHTML from './ShowRenderedHTML.js';

function Tracking() {
  return (
    <script>
      ga('send', 'pageview');
    </script>
  );
}

export default function Page() {
  return (
    <ShowRenderedHTML>
      <h1>My Website</h1>
      <Tracking />
      <p>Welcome</p>
    </ShowRenderedHTML>
  );
}

💡 부연 설명: 인라인 스크립트와 외부 스크립트의 처리 방식이 다르다는 점을 기억하세요!

  • 외부 스크립트 (src prop 사용): async={true}와 함께 사용하면 <head>로 이동되고 중복 제거돼요.
  • 인라인 스크립트 (children 사용): 렌더링된 위치에 그대로 남아있고, 중복 제거되지 않아요.

따라서 같은 인라인 스크립트를 여러 번 렌더링하면 여러 번 실행될 수 있으니 주의하세요!

profile
프론트에_가까운_풀스택_개발자

0개의 댓글