커스텀 위젯 설정패널 만들기

커스텀 위젯 스튜디오 설정패널 만들기

변수 탭은 설정 패널을 만드는 하나의 JSONC 문서예요. 문서를 통째로 붙여넣으면 패널이 그 기준으로 다시 구성됩니다.
이 도움말에서는 변수 탭 문서를 작성하는 방법을 알아보실 수 있어요.

📢 안내 | 기존의 코드 주석 방식({{!-- @name ... --}})은 더 이상 파싱되지 않아요. 설정패널 정의는 변수 탭 문서 하나로만 관리합니다.

목차

  1. 변수 탭 문서 구조
  2. 그룹 규칙
  3. 변수 선언하기
  4. 지원 타입 10종
  5. 저장이 막히거나 항목이 보이지 않을 때

1. 변수 탭 문서 구조

문서 전체가 하나의 JSON 객체입니다. 최상위 키 하나가 그룹 또는 변수가 되고, 선언한 순서가 곧 설정 패널에 보이는 순서입니다.

{
  // 카드 간격을 조절할 수 있습니다
  "레이아웃": {
    "opened": false,
    "children": {
      "text-gap": {
        "type": "textfield",
        "label": "카드 간 간격",
        "default": "16",
        "suffix": "px"
      }
    }
  }
}

1-1. JSONC 문법

변수 탭은 일반 JSON이 아니라 JSONC(주석을 쓸 수 있는 JSON)입니다.

// 라인 주석은 단순 메모가 아니라 설정 패널의 안내 문구로 표시됩니다. 최대 35자까지 쓸 수 있습니다.

  • 최상위에 쓴 주석은 패널 최상단 안내 문구가 됩니다.
  • 그룹의 children 안에 쓴 주석은 그 그룹의 안내 문구가 됩니다.
  • 주석 바로 다음 항목 앞에 표시되며, 컨테이너 끝에 쓴 주석은 맨 끝에 표시됩니다.
  • 변수 정의 객체 안쪽에 쓴 주석은 표시되지 않고 버려집니다.

그 밖의 문법 규칙은 아래와 같습니다.

  • 마지막 항목 뒤의 쉼표(trailing comma)를 사용할 수 있습니다.
  • 블록 주석은 사용할 수 없습니다. /* */ 를 쓰면 파싱에 실패해 패널이 반영되지 않고 저장도 막힙니다.
  • 빈 문서는 파싱에 실패합니다. 변수가 없더라도 최소한 {} 는 남겨 주세요.

1-2. 그룹과 변수 구분하기

구분그룹변수
판별 기준type 없이 children 이 있습니다type 이 있습니다
키의 의미운영자에게 보이는 그룹 이름 (한국어)변수명 (영문 kebab-case)
예시"레이아웃": { "children": { ... } }"text-gap": { "type": "textfield", ... }
주의

typechildren 도 없는 객체는 오류 표시 없이 조용히 사라집니다. 저장은 되지만 패널에 항목이 나타나지 않습니다. type 누락이 가장 흔한 사고입니다.

2. 그룹 규칙

규칙어기면
그룹 이름은 최대 18자저장 불가
빈 그룹은 만들 수 없습니다 (하위 항목 최소 1개)저장 불가
그룹 안에 그룹을 넣을 수 없습니다안쪽 그룹과 그 자식이 통째로 조용히 사라집니다
변수명은 그룹과 무관하게 전역에서 유일해야 합니다저장 불가

opened 는 그룹을 펼친 채로 열지 정하는 값입니다. 선택 항목이며 boolean으로 씁니다.

TIP

opened 를 생략하면 기본값이 true 라서 모든 그룹이 펼쳐진 채로 열립니다. 항목이 많으면 패널이 길어져 찾기 어려워집니다. 첫 번째 그룹 하나만 펼쳐 두고, 나머지 그룹에는 "opened": false 를 명시하는 것을 권장합니다.

3. 변수 선언하기

변수 하나는 "변수명": { 정의 } 형태입니다. typelabel 은 필수입니다.

"color-title": {
  "type": "color",
  "label": "타이틀 컬러",
  "default": "#FFFFFF"
}

label 을 넣지 않으면 설정 패널에 변수명이 그대로 노출되므로 반드시 넣어 주세요.

3-1. 변수명 규칙

반드시 지켜야 합니다. 어기면 저장할 수 없습니다.

  • 영문으로 시작하고 영문, 숫자, 하이픈(-) 만 쓸 수 있습니다. 언더스코어, 공백, 특수문자는 사용할 수 없습니다.
  • 최대 30자이며, 하이픈으로 끝날 수 없습니다.
  • typewidget 은 예약어라 사용할 수 없습니다. _ 로 시작하거나 imweb 으로 시작하는 이름도 사용할 수 없습니다.
  • 그룹과 무관하게 전역에서 유일해야 합니다.
  • 위젯 코드의 {{토큰}} 과 철자가 완전히 같아야 합니다.

권장 사항

소문자 kebab-case로 쓰고, 4번 항목 표의 타입 접두사를 붙여 주세요. 30자를 넘길 것 같으면 의미를 유지하면서 줄이면 됩니다. 예를 들어 text-card-title-font-size-desktop(33자)은 text-card-title-size-pc(23자)로 줄일 수 있습니다.

// 올바른 예
"color-btnbg": { "type": "color", "label": "버튼 배경 컬러" }

// 잘못된 예 — 접두사가 color- 가 아닙니다
"btn-bg": { "type": "color", "label": "버튼 배경 컬러" }

// 잘못된 예 — 숫자를 넣는 입력창도 text- 입니다
"num-size": { "type": "textfield", "label": "텍스트 크기" }

3-2. 인식되는 키 9개

정의비고
type패널 화면 타입color(색상 패널), textfield(입력창) 등
label라벨 명
default기본값
placeholder플레이스홀더
values목록 내 선택값목록 선택(select), 세그먼트(segment)에서 사용합니다
valueNames목록 내 선택값의 명칭
suffix접미사px, 등 단위
maxLength아이템 최대 개수maxLength: 10 이면 아이템(반복 요소)을 10개까지만 추가할 수 있습니다
fields아이템 하위 자식 변수들의 타입 정의아이템(item)에서 사용합니다

키를 잘못 쓰면 결과가 두 가지로 갈립니다.

  • 목록에 없는 키 (options, 오타 등) → 경고만 표시되고 무시됩니다.
  • 목록에 있지만 그 타입에서 쓸 수 없는 키 (switchplaceholder, textfield 밖의 suffix 등) → 저장이 막힙니다.

3-3. 단위 표기 (suffix)

숫자 입력창 오른쪽에 붙는 단위 표시입니다. 입력창(textfield)에서만 쓸 수 있고 다른 타입에 쓰면 저장이 막힙니다. 최대 5자입니다.

단위는 label 이나 default 가 아니라 suffix 에 넣어 주세요.

// 올바른 예
{ "type": "textfield", "label": "모서리 둥글기", "default": "8", "suffix": "px" }

// 잘못된 예
{ "type": "textfield", "label": "모서리 둥글기", "default": "8px" }
{ "type": "textfield", "label": "모서리 둥글기 (px)", "default": "8" }

4. 지원 타입 10종

type패널 화면변수명 접두사용 가능 키 (label 외)default 형식
textfield입력창text-default placeholder suffix"342" — 단위 없는 문자열
text-editor텍스트 에디터editor-default placeholderMarkdown 문자열
select목록 선택select-values(필수) valueNames default placeholdervalues 중 하나
segment세그먼트segment-values(필수) valueNames default placeholdervalues 중 하나
color색상 선택color-default placeholder#RRGGBB 또는 #RRGGBBAA (3자리, rgba, hsl 불가)
image이미지 업로더image-placeholder사용하지 않습니다 (default 키 자체를 넣지 않습니다)
date날짜 선택date-default placeholder"2026.08.05" — 점으로 구분
time시간 선택time-default placeholder"오전 9시 00분"
switch스위치switch-default 만 (placeholder 불가)따옴표 없는 true / false
item아이템item-fields(필수) default maxLength인스턴스 객체 배열 (4-2 항목 참조)
  • switchdefault"true" 문자열이 아니라 따옴표 없는 true 입니다. 코드에서 {{토큰}} 으로 받는 값은 "true" 문자열이지만, 정의할 때는 boolean입니다.
  • image 는 운영자가 이미지를 올리지 않아도 플랫폼이 회색 플레이스홀더 이미지를 넣어 줍니다. 빈 값이 전달되지 않습니다.

4-1. 목록 선택 · 세그먼트 옵션

옵션은 values(내부 값)와 valueNames(화면에 보이는 이름) 두 배열로 정의합니다.

"segment-align": {
  "type": "segment",
  "label": "정렬",
  "default": "center",
  "values":     ["left", "center", "right"],
  "valueNames": ["왼쪽",  "가운데",  "오른쪽"]
}
  • values 는 필수이며 1개 이상이어야 합니다. valueNames 를 쓸 때는 두 배열의 개수가 정확히 같아야 합니다.
  • default 는 반드시 values 안에 있는 값이어야 합니다.
  • 옵션이 2~3개면 세그먼트, 4개 이상이면 목록 선택을 사용하는 것을 권장합니다. segment 는 최대 4개, select 는 최대 10개까지 만들 수 있습니다.
  • 옵션 이름은 segment 최대 8자, select 최대 51자입니다.
  • values 는 영문 소문자와 하이픈으로, valueNames 는 한국어로 작성해 주세요.
  • "없음" 선택지가 있다면 첫 번째에 두고 없음 = none 으로 짝지어 주세요.
  • options 키는 인식되지 않습니다. 반드시 valuesvalueNames 를 사용해 주세요.

4-2. 아이템 (반복 항목)

카드, 슬라이드, 목록처럼 같은 형태가 여러 개 반복되는 콘텐츠는 아이템으로 만듭니다. fields 가 하위 필드의 정의이고, default실제로 깔아 둘 초기 행입니다.

4-2-1. 기본 구조

"item-cards": {
  "type": "item",
  "label": "카드 아이템",
  "maxLength": 10,
  "fields": {
    "image-card":    { "type": "image",       "label": "카드 이미지" },
    "editor-title":  { "type": "text-editor", "label": "텍스트 1" },
    "text-btnlabel": { "type": "textfield",   "label": "버튼 문구",
                       "placeholder": "미입력 시 미노출" },
    "text-link":     { "type": "textfield",   "label": "링크", "placeholder": "https://" },
    "switch-newtab": { "type": "switch",      "label": "새창으로 이동" }
  },
  "default": [
    { "image-card": "", "editor-title": "**첫 번째 카드**", "text-btnlabel": "자세히 보기",
      "text-link": "", "switch-newtab": false },
    { "image-card": "", "editor-title": "**두 번째 카드**", "text-btnlabel": "자세히 보기",
      "text-link": "", "switch-newtab": false },
    { "image-card": "", "editor-title": "**세 번째 카드**", "text-btnlabel": "자세히 보기",
      "text-link": "", "switch-newtab": false }
  ]
}

위젯 코드에서는 Handlebars의 each 문법으로 반복하며, 하위 필드는 접두어 없이 그대로 참조합니다.

4-2-2. 제한 사항

규칙어기면
하위 필드 정의에는 기본값을 두지 않습니다fields 안에 default 를 쓰지 말고, 값은 전부 default 인스턴스 배열에 넣습니다저장 불가
default 인스턴스의 키는 fields 에 선언한 이름과 정확히 일치해야 합니다저장 불가
하위 필드 타입은 item 을 뺀 9종입니다 — 아이템 안에 아이템을 넣을 수 없습니다저장 불가
maxLength 는 1~20 정수입니다(생략 시 20). default 행 수보다 작으면 안 됩니다저장 불가
아이템은 한 위젯에 1종만 쓸 수 있습니다 — 항목 개수 제한이 아니라 배열 종류 제한입니다저장 불가
default 행은 최대 20행, 하위 필드는 최대 20종입니다저장 불가
하위 필드명이 최상위 변수명과 겹치면 안 됩니다에디터가 최상위 변수로 해석해 하위 필드가 "미사용"으로 표시됩니다

4-2-3. 자주 하는 실수

초기 행을 빈 값으로 두는 경우

default 의 각 행에는 그 항목의 실제 내용을 채워 주세요. 행마다 값이 서로 달라도 됩니다. 단, image 하위 필드의 값은 빈 문자열 "" 로 두세요.

모든 행의 값이 똑같은 경우

운영자가 무엇을 바꿔야 할지 알기 어렵습니다. 카드가 3개라면 세 카드의 문구를 각각 다르게 넣어 주세요.

하위 필드에 접두사를 반드시 붙여야 한다고 생각하는 경우

하위 필드는 접두사가 선택 사항입니다. questiontext-question 도 괜찮습니다. 접두사보다 최상위 변수명과 겹치지 않게 짓는 것이 더 중요합니다.

TIP

아이템 라벨은 {내용물} 아이템 또는 {내용물} 목록 형태로 지어 주세요. 기본 제공 위젯은 카드 아이템, 롤링 아이템, 슬라이드 목록, 메뉴 아이템 처럼 사용하고 있습니다.

5. 저장이 막히거나 항목이 보이지 않을 때

저장 자체가 되지 않습니다

문법 오류이거나 규칙을 어긴 경우입니다. 아래를 순서대로 확인해 주세요.

  • 블록 주석 /* */ 을 사용하지 않았는지
  • 문서가 비어 있지 않은지 (최소한 {} 가 있어야 합니다)
  • 변수명이 중복되지 않았는지 (그룹과 무관하게 전역에서 유일해야 합니다)
  • 변수명에 언더스코어, 공백, 특수문자가 들어가지 않았는지
  • 그룹 이름이 18자를 넘지 않는지, 빈 그룹이 없는지
  • 그 타입에서 쓸 수 없는 키를 넣지 않았는지 (switchplaceholder, textfield 밖의 suffix 등)

저장은 되는데 패널에 항목이 보이지 않습니다

오류 메시지가 뜨지 않는 경우입니다. 아래 세 가지를 확인해 주세요.

  • type 을 빠뜨리지 않았는지 — typechildren 도 없는 객체는 조용히 사라집니다.
  • 그룹 안에 그룹을 넣지 않았는지 — 안쪽 그룹과 그 자식이 통째로 사라집니다.
  • 아이템의 하위 필드명이 최상위 변수명과 겹치지 않는지 — 겹치면 "미사용"으로 표시됩니다.

패널에는 보이는데 위젯에 값이 반영되지 않습니다

변수명과 위젯 코드의 {{토큰}} 철자가 완전히 같은지 확인해 주세요. 대소문자와 하이픈 위치까지 일치해야 합니다.

함께 보면 좋은 가이드

목록으로