For developers · Runtime Bridge

개발자용 · 런타임 브리지

Put a "Take the tour" button on your own page.

내 사이트에 '둘러보기' 버튼 달기.

The bridge is a small remote control: your page asks an installed Manuscript extension to replay a saved tour. It shines when your visitors are likely to have the extension — or when you want them to install it. Need playback with no extension at all? Use the standalone player instead, and see Bridge vs Player to choose.

브리지는 작은 리모컨입니다. 내 페이지가 설치된 Manuscript 확장에 저장된 투어 재생을 부탁합니다. 방문자에게 확장이 있을 가능성이 높거나 설치를 유도하고 싶을 때 좋아요. 확장 없이 재생해야 한다면 스탠드얼론 플레이어를 쓰고, 선택은 브리지 vs 플레이어에서 확인하세요.

Extension 확장 play() drives replay 재생 실행 your-site.com manuscript-bridge Take the tour 둘러보기 any-site.com replaying 재생 중 your page = remote control 내 페이지 = 리모컨 any page · any domain 아무 페이지 · 아무 도메인 visitors need the Manuscript extension installed 방문자에게 Manuscript 확장 설치가 필요

Embed it on your own site

내 사이트에 끼워 넣기

Put a "Take the tour" button on your own page.

내 사이트에 '둘러보기' 버튼 달기.

Your visitors need the Manuscript extension installed. The bridge is a remote control rather than a player on its own. When a visitor doesn't have the extension yet, the bridge can either pop a small install prompt itself or hand the moment back to you via manuscript.openStore() / manuscript.openHomepage(). Both behaviors are opt-in — the bridge never injects UI you didn't ask for.
방문자에게 Manuscript 확장이 설치되어 있어야 합니다. 브리지는 사이트 안에서 시연을 실행하는 리모컨 역할이라, 확장이 없으면 (a) 브리지가 작은 설치 안내를 직접 띄워주거나 (b) manuscript.openStore() / manuscript.openHomepage() 로 그 순간을 직접 다룰 수 있어요. 두 방식 모두 옵션 — 호출하지 않은 UI 는 브리지가 알아서 띄우지 않습니다.

manuscript-bridge.0.1.3.js is a small, dependency-free file (about 14 KB) you drop onto your page. From there, your "Take the tour" button can load a saved tour and ask Manuscript to play it — the spotlights, notes, and narration take care of themselves. By default playback is read-only and cleans up after itself once the tour ends.

manuscript-bridge.0.1.3.js 는 의존성 없는 약 14 KB 짜리 작은 파일입니다. 내 페이지에 넣어두기만 하면, "둘러보기" 같은 버튼으로 저장해 둔 시연을 불러와 Manuscript 에 재생을 부탁할 수 있어요. 강조 표시·메모·음성 안내는 알아서 처리됩니다. 기본 재생은 보기 전용이며 시연이 끝나면 흔적 없이 깔끔하게 정리됩니다.

One narration caveat: browsers block sound on a page opened without a click, so if a tour auto-advances to another page, that page's narration waits for the viewer to click (the speaker turns orange with a "click anywhere for sound" hint). Pages the viewer advances by clicking keep sound flowing.
내레이션 유의점 한 가지: 브라우저는 클릭 없이 열린 페이지의 소리를 막습니다. 그래서 투어가 다른 페이지로 자동 진행하면 그 페이지의 음성은 보는 사람이 클릭할 때까지 기다립니다(스피커가 주황색으로 바뀌며 "아무 곳이나 클릭하세요" 안내가 떠요). 보는 사람이 클릭으로 넘긴 페이지는 소리가 이어집니다.

Option A — your own button

방법 A — 내 버튼 직접 만들기

Most common pattern. You author the button (any styling you want) and wire it to the bridge. When the extension is missing, send the visitor to the Web Store with openStore(); optionally to your own product page with openHomepage().

가장 자주 쓰는 패턴. 버튼은 직접 만들고(원하는 디자인 그대로) 브리지에 연결만 합니다. 확장이 없으면 openStore() 로 웹 스토어로 보내고, 옵션으로 openHomepage() 로 본인 제품 페이지로도 안내할 수 있어요.

<!-- in your page -->
<script src="/manuscript-bridge.0.1.3.js"></script>
<button id="start">Take the tour</button>

<script>
  // Opt in to the homepage fallback — without this, openHomepage() warns and no-ops.
  manuscript.configure({
    homepageUrl: 'https://zendy00.github.io/manuscript-pages/',
    banner: false,  // suppress the bridge's built-in install prompt — we handle it below
  });

  const btn = document.getElementById('start');

  btn.addEventListener('click', async () => {
    if (!(await manuscript.isInstalled())) {
      manuscript.openStore();         // or: manuscript.openHomepage()
      return;
    }
    btn.hidden = true;
    const scenario = await fetch('/tours/tour-en.json').then(r => r.json());
    await manuscript.load(scenario);
    await manuscript.play({ standalone: true });
  });

  manuscript.onExit(() => { btn.hidden = false; });
</script>
<!-- 호스트 페이지 안에 둡니다 -->
<script src="/manuscript-bridge.0.1.3.js"></script>
<button id="start">투어 시작</button>

<script>
  // 홈페이지 fallback 은 opt-in — 호출하지 않으면 openHomepage() 는 경고만 출력하고 no-op.
  manuscript.configure({
    homepageUrl: 'https://zendy00.github.io/manuscript-pages/',
    banner: false,  // 기본 설치 안내 끄기 — 아래에서 직접 처리
  });

  const btn = document.getElementById('start');

  btn.addEventListener('click', async () => {
    if (!(await manuscript.isInstalled())) {
      manuscript.openStore();         // 또는: manuscript.openHomepage()
      return;
    }
    btn.hidden = true;
    const scenario = await fetch('/tours/tour-ko.json').then(r => r.json());
    await manuscript.load(scenario);
    await manuscript.play({ standalone: true });
  });

  manuscript.onExit(() => { btn.hidden = false; });
</script>

Option B — let the bridge mount the launcher

방법 B — 브리지가 런처를 직접 띄우기

Zero-DOM-touch path. mountLauncher() attaches a Shadow-DOM-isolated pill to the bottom-right of your page. When the extension is installed it reads "Take the tour" and runs the configured scenario on click; when it's missing the same pill morphs into "Install Manuscript" (plus an optional "Learn more" link if you set homepageUrl). A small ✕ on the install prompt persists dismissal to localStorage.

DOM 안 건드리는 경로. mountLauncher() 가 Shadow DOM 격리된 pill 을 페이지 우하단에 띄웁니다. 확장이 설치돼 있으면 "투어 시작" 으로, 미설치면 같은 자리에 "Manuscript 설치" 가 뜨고 homepageUrl 을 지정해 두면 "자세히 보기" 링크도 함께 나옵니다. 안내의 ✕ 닫기 버튼은 localStorage 에 기억되어 같은 사이트에서 다시 뜨지 않아요.

<!-- in your page -->
<script src="/manuscript-bridge.0.1.3.js"></script>
<script>
  manuscript.configure({
    homepageUrl: 'https://zendy00.github.io/manuscript-pages/',  // optional "Learn more"
    lang: 'auto',           // 'auto' (default) / 'en' / 'ko'
  });

  manuscript.mountLauncher({
    scenarioUrl: '/tours/tour-en.json',  // or scenario: {...}
    label: 'Take the tour',             // optional override
  });
</script>
<!-- 호스트 페이지 안에 둡니다 -->
<script src="/manuscript-bridge.0.1.3.js"></script>
<script>
  manuscript.configure({
    homepageUrl: 'https://zendy00.github.io/manuscript-pages/',  // 옵션: "자세히 보기"
    lang: 'auto',           // 'auto'(기본) / 'en' / 'ko'
  });

  manuscript.mountLauncher({
    scenarioUrl: '/tours/tour-ko.json',  // 또는 scenario: {...}
    label: '투어 시작',                  // 옵션: 라벨 직접 지정
  });
</script>

Public API (manuscript.*)

공개 API (manuscript.*)

// ── Discovery
manuscript.isInstalled()                    // → Promise<boolean> (cached per page)
manuscript.refreshInstalled()               // re-ping, bust the cache

// ── Lifecycle
manuscript.load(scenario)                   // object or JSON string
manuscript.play({ startIndex, paused, standalone })
manuscript.pause() / manuscript.next() / manuscript.prev()
manuscript.jump(index)
manuscript.exit()

// ── Navigation (new in 0.1.3) — works with or without a launcher
manuscript.openStore()                      // opens the extension store in a new tab
manuscript.openHomepage()                   // opens configured homepageUrl, or warns + no-ops

// ── Auto-mounted launcher (new in 0.1.3)
manuscript.mountLauncher({ scenarioUrl, scenario, label, standalone })
manuscript.unmountLauncher()

// ── Configure
manuscript.configure({
  banner: true,                         // show install prompt on missing extension
  timeoutMs: 1500,
  lang: 'auto',                          // 'auto' | 'en' | 'ko'
  storeUrl: 'https://chromewebstore.google.com/...',
  homepageUrl: 'https://example.com',     // opt-in extra link
  onInstallClick: () => analytics.track('mn:install'),
  onHomeClick:    () => analytics.track('mn:learn-more'),
})

// ── Replay-end — fires on ✕ or natural end of tour
const off = manuscript.onExit(() => { /* restore your UI */ });
// off()  ← call to unregister
// or:    window.addEventListener('manuscript:exited', handler)
// ── 발견
manuscript.isInstalled()                    // → Promise<boolean> (페이지 내 캐시)
manuscript.refreshInstalled()               // 캐시 초기화 후 재핑

// ── 라이프사이클
manuscript.load(scenario)                   // 객체 또는 JSON 문자열
manuscript.play({ startIndex, paused, standalone })
manuscript.pause() / manuscript.next() / manuscript.prev()
manuscript.jump(index)
manuscript.exit()

// ── 이동 API (0.1.3 신규) — 런처 유무와 무관하게 호출 가능
manuscript.openStore()                      // 새 탭에서 확장 스토어 열기
manuscript.openHomepage()                   // homepageUrl 열기 (미설정 시 경고 + no-op)

// ── 자동 마운트 런처 (0.1.3 신규)
manuscript.mountLauncher({ scenarioUrl, scenario, label, standalone })
manuscript.unmountLauncher()

// ── 설정
manuscript.configure({
  banner: true,                         // 확장 미설치 시 설치 안내 자동 표시
  timeoutMs: 1500,
  lang: 'auto',                          // 'auto' | 'en' | 'ko'
  storeUrl: 'https://chromewebstore.google.com/...',
  homepageUrl: 'https://example.com',     // opt-in 추가 링크
  onInstallClick: () => analytics.track('mn:install'),
  onHomeClick:    () => analytics.track('mn:learn-more'),
})

// ── 재생 종료 — ✕ 클릭 또는 마지막 step 완료 시
const off = manuscript.onExit(() => { /* 사용자 UI 복원 */ });
// off()  ← 호출해서 등록 해제
// 또는:  window.addEventListener('manuscript:exited', handler)

Downloads

다운로드

manuscript-bridge.0.1.3.js (current)

The bridge library. openStore(), openHomepage(), mountLauncher(), and a Shadow-DOM-isolated install prompt. Drop it into your page and the manuscript.* global appears. The legacy manuscript-bridge.0.1.2.js URL stays live as an alias of this same file, so hosts pinned to it keep working unchanged.

브리지 라이브러리. openStore(), openHomepage(), mountLauncher() 와 Shadow DOM 격리된 설치 안내가 포함됩니다. 페이지에 추가하면 manuscript.* 전역이 노출됩니다. 구버전 manuscript-bridge.0.1.2.js URL 도 이 파일의 alias 로 그대로 살아 있어, 이 URL 에 고정해 둔 호스트는 무수정으로 계속 동작합니다.

↓ Download 0.1.3

Tour JSON (example)

Example only — not a template for your site. A short tour of this landing page. Selectors target elements that exist here (#features, #install, …) and will not match your own page. Use it as a reference shape, then author your own with the Manuscript extension and Export it for your URL. English and Korean versions share the same selectors — only narration and step names differ.

예제일 뿐 — 본인 사이트 템플릿이 아닙니다. 랜딩 페이지를 짧게 안내하는 투어입니다. 셀렉터가 이 페이지의 요소(#features, #install 등)를 가리키므로 본인 페이지에서는 매칭되지 않습니다. 구조만 참고하고, 본인 URL용 투어는 Manuscript 확장으로 작성해 내보내기(Export)하세요. 영어·한국어 버전은 셀렉터가 동일하며 narration과 step 이름만 다릅니다.