[Part 4] Web Components — Template & Slot으로 유연한 구조 만들기
template 태그로 파싱 비용을 줄이고, slot으로 외부 콘텐츠를 삽입하는 패턴. named slot과 slotchange 이벤트 활용법까지 다룹니다.
[Part 4] Web Components — Template & Slot으로 유연한 구조 만들기
Part 3에서는 Shadow DOM을 사용해서 컴포넌트 내부 구조와 스타일을 외부와 분리하는 방법을 알아봤다.
이번 글에서는 Web Components의 또 다른 핵심 기술인 Template과 Slot을 알아본다.
Template은 반복해서 사용할 HTML 구조를 미리 보관하는 기술이다.
Slot은 컴포넌트 외부에서 전달한 내용을 내부 특정 위치에 표시하는 기술이다.
두 개념은 Web Components를 더 재사용 가능하고 유연하게 만드는 데 중요하다.
1. 왜 Template이 필요할까?
AD
제휴 광고 · 일부 링크는 수수료를 받을 수 있습니다
Custom Element 안에서 HTML을 만들 때 가장 간단한 방법은 innerHTML을 사용하는 것이다.
class MyCard extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<article>
<h3>카드 제목</h3>
<p>카드 내용</p>
</article>
`;
}
}
customElements.define('my-card', MyCard);
이 방식은 간단하다.
하지만 컴포넌트 구조가 길어질수록 JavaScript 문자열 안에 HTML을 계속 작성해야 한다.
모달, 카드, 메뉴, 상품 목록처럼 구조가 복잡한 컴포넌트에서는 코드가 읽기 어려워질 수 있다.
이럴 때 사용할 수 있는 것이 <template>이다.
2. Template이란?
Template은 화면에 바로 표시되지 않는 HTML 보관함이다.
일반 HTML은 작성하면 바로 화면에 렌더링된다.
<article>
<h3>카드 제목</h3>
<p>카드 내용</p>
</article>
하지만 <template> 안에 작성한 HTML은 화면에 바로 보이지 않는다.
<template id="card-template">
<article>
<h3>카드 제목</h3>
<p>카드 내용</p>
</article>
</template>
브라우저는 template 안의 내용을 가지고는 있지만, 화면에는 출력하지 않는다.
필요한 시점에 JavaScript로 복사해서 사용할 수 있다.
3. Template 기본 사용법
먼저 HTML에 template을 작성한다.
<template id="card-template">
<article>
<h3>카드 제목</h3>
<p>카드 내용</p>
</article>
</template>
JavaScript에서 template을 선택한다.
const template = document.querySelector('#card-template');
template 안의 내용을 복사한다.
const clone = template.content.cloneNode(true);
그리고 실제 화면에 추가한다.
document.body.appendChild(clone);
코드 리뷰
document.querySelector('#card-template')은 id가 card-template인 template 요소를 선택한다.
template.content는 template 안에 들어있는 실제 HTML 구조를 의미한다.
cloneNode(true)는 template 내용을 복사한다.
true는 자식 요소까지 전부 복사하겠다는 뜻이다.
appendChild()는 복사한 내용을 DOM에 추가한다.
4. Template과 Shadow DOM 함께 사용하기
Web Components에서는 Template과 Shadow DOM을 함께 사용하는 경우가 많다.
<template id="card-template">
<style>
article {
padding: 16px;
border: 1px solid #ddd;
border-radius: 8px;
}
</style>
<article>
<h3>카드 제목</h3>
<p>카드 내용</p>
</article>
</template>
그리고 Custom Element에서 이 template을 Shadow DOM 안에 넣는다.
class MyCard extends HTMLElement {
connectedCallback() {
const template = document.querySelector('#card-template');
const shadow = this.attachShadow({
mode: 'open'
});
const clone = template.content.cloneNode(true);
shadow.appendChild(clone);
}
}
customElements.define('my-card', MyCard);
이렇게 하면 template 구조를 재사용하면서 Shadow DOM으로 스타일도 격리할 수 있다.
5. Slot이란?
Slot은 외부에서 전달한 내용을 컴포넌트 내부 특정 위치에 표시하는 기술이다.
예를 들어 버튼 컴포넌트를 만든다고 해보자.
버튼 구조와 스타일은 같지만 버튼 안의 텍스트는 매번 다를 수 있다.
<my-button>저장</my-button>
<my-button>삭제</my-button>
<my-button>수정</my-button>
이때 컴포넌트 내부에서 <slot>을 사용하면 외부에서 전달한 텍스트를 내부에 표시할 수 있다.
6. 기본 Slot 사용법
template 안에 slot을 넣어보자.
<template id="button-template">
<button>
<slot></slot>
</button>
</template>
컴포넌트는 다음처럼 만든다.
class MyButton extends HTMLElement {
connectedCallback() {
const template = document.querySelector('#button-template');
const shadow = this.attachShadow({
mode: 'open'
});
shadow.appendChild(
template.content.cloneNode(true)
);
}
}
customElements.define('my-button', MyButton);
HTML에서는 이렇게 사용한다.
<my-button>저장</my-button>
그러면 저장이라는 텍스트가 <slot> 위치에 들어간다.
코드 리뷰
<slot></slot>은 외부 콘텐츠가 들어갈 자리다.
<my-button>저장</my-button>에서 저장이라는 텍스트가 slot 위치에 표시된다.
7. Named Slot
slot이 하나만 있으면 기본 slot으로 충분하다.
하지만 카드처럼 제목과 내용을 따로 받고 싶을 때는 이름이 있는 slot을 사용한다.
<template id="card-template">
<article>
<h3>
<slot name="title"></slot>
</h3>
<p>
<slot name="content"></slot>
</p>
</article>
</template>
사용할 때는 slot attribute를 지정한다.
<my-card>
<span slot="title">카드 제목</span>
<span slot="content">카드 내용입니다.</span>
</my-card>
slot="title"은 <slot name="title"> 위치로 들어간다.
slot="content"는 <slot name="content"> 위치로 들어간다.
8. Slot을 사용하는 이유
Slot을 사용하면 컴포넌트 구조는 유지하면서 내용만 외부에서 바꿀 수 있다.
예를 들어 같은 카드 컴포넌트라도 제목과 내용만 다르게 사용할 수 있다.
<my-card>
<span slot="title">공지사항</span>
<span slot="content">서비스 점검 안내입니다.</span>
</my-card>
<my-card>
<span slot="title">이벤트</span>
<span slot="content">신규 가입 이벤트가 진행 중입니다.</span>
</my-card>
컴포넌트 내부 구조는 같지만 내용은 다르게 표시된다.
9. Attribute와 Slot의 차이
외부 값을 전달할 때 attribute를 사용할 수도 있고 slot을 사용할 수도 있다.
attribute는 짧은 값이나 설정 값을 전달할 때 좋다.
<my-button variant="primary">저장</my-button>
slot은 HTML 콘텐츠 자체를 전달할 때 좋다.
<my-card>
<span slot="title">제목</span>
<span slot="content">내용</span>
</my-card>
정리하면 다음과 같다.
- 짧은 설정 값은 attribute가 적합하다.
- HTML 콘텐츠를 넣어야 하면 slot이 적합하다.
10. Template과 Slot을 함께 사용한 예제
<template id="info-card-template">
<style>
article {
padding: 16px;
border: 1px solid #ddd;
border-radius: 8px;
font-family: sans-serif;
}
h3 {
margin: 0 0 8px;
}
p {
margin: 0;
color: #555;
}
</style>
<article>
<h3>
<slot name="title"></slot>
</h3>
<p>
<slot name="content"></slot>
</p>
</article>
</template>
<info-card>
<span slot="title">Web Components</span>
<span slot="content">브라우저 표준 기반 컴포넌트 기술입니다.</span>
</info-card>
<script>
class InfoCard extends HTMLElement {
connectedCallback() {
const template = document.querySelector('#info-card-template');
const shadow = this.attachShadow({
mode: 'open'
});
shadow.appendChild(
template.content.cloneNode(true)
);
}
}
customElements.define('info-card', InfoCard);
</script>
이 예제는 Template, Slot, Shadow DOM, Custom Elements를 함께 사용한다.
11. 정리
AD
제휴 광고 · 일부 링크는 수수료를 받을 수 있습니다
Template과 Slot은 Web Components를 유연하게 만드는 핵심 기술이다.
- Template은 재사용할 HTML 구조를 보관한다.
- Template 안의 내용은 화면에 바로 보이지 않는다.
- template.content로 내부 내용을 가져올 수 있다.
- cloneNode(true)로 구조를 복사해서 사용한다.
- Slot은 외부 콘텐츠를 컴포넌트 내부에 표시한다.
- Named Slot을 사용하면 여러 위치에 콘텐츠를 나눠 넣을 수 있다.
- attribute는 설정 값에 좋고 slot은 HTML 콘텐츠 전달에 좋다.
다음 Part에서는 Web Components의 생명주기인 Lifecycle Callbacks를 알아본다.
AD
제휴 광고
일부 링크는 제휴 링크이며, 구매 또는 가입 시 일정 수수료를 받을 수 있습니다.
AD
'Web components' 카테고리의 다른 글
전체보기- [Part 4] Web Components — Template & Slot으로 유연한 구조 만들기 현재 글
- [Part 5] Web Components — Lifecycle Callbacks 완전 이해 2026.04.29
- [Part 6] Web Components — Custom Events와 컴포넌트 통신 2026.05.06
- [Part 7] Web Components — 고급 스타일링 전략 2026.05.13
- [Part 8] Web Components — Form 연동과 ElementInternals 2026.05.20
- [Part 9] Web Components — static template 패턴 & 메모리 최적화 2026.05.27









