導覽

整合

在你的應用程式中嵌入編輯器

了解如何把 Bannerify 編輯器放進你的產品,讓使用者用你的範本進行設計。

當你的使用者需要在你的產品內製作橫幅、貼文、標籤或文件時,請使用嵌入功能。你的頁面會在 iframe 中顯示 Bannerify 編輯器。每位使用者都有自己的設計,也可以從你工作區的範本開始。

運作方式

  1. 你的伺服器用嵌入功能的簽署密鑰,為使用者簽署一個短效的權杖。
  2. 你的頁面在 iframe 中開啟 https://embed.bannerify.co/<embed id>?token=<token>。
  3. Bannerify 檢查權杖和頁面的網域,然後為該使用者開啟編輯器。
  4. 使用者的設計是你工作區中的範本。你可以像其他範本一樣,用 API 繪製它們。

先決條件

  • 一個 Scale 或 Enterprise 方案的工作區。
  • 一個能簽署 JWT 的伺服器。簽署密鑰必須留在你的伺服器上。
Scale Enterprise
允許的網域 3 8
編輯器使用者 100 500
下載、權限、名稱、標誌和強調色 有 有
SDK 事件與指令 有 有
Webhook 有 有
隱藏 Bannerify 品牌 無 有
來自你應用程式的素材選擇器 無 有
分析 無 有

設定嵌入功能

  1. 開啟儀表板側邊欄中的 Embed。
  2. 點選 Set up the embed,然後開啟 Turn on the embed。
  3. 在 Allowed domains 底下,加入每個會顯示編輯器的頁面的來源,例如 https://app.example.com。所有子網域請用 https://*.example.com,開發期間則用 http://localhost:3000。
  4. 複製 Embed id 和 Signing secret。

在你的伺服器上簽署權杖

權杖是 HS256 的 JWT。請把 sub 設為使用者在你應用程式中的 ID。相同的 sub 一律會開啟相同的設計。

import { SignJWT } from "jose"

const token = await new SignJWT({ sub: user.id, name: user.name, email: user.email })
  .setProtectedHeader({ alg: "HS256" })
  .setExpirationTime("1h")
  .sign(new TextEncoder().encode(process.env.BANNERIFY_EMBED_SECRET))
宣告 必填 說明
sub 否 使用者在你應用程式中的 ID。可使用英文字母、數字、_、-、@ 和 .,最多 256 個字元。沒有它時,編輯器會編輯你工作區的範本。
name 否 使用者的名稱。
email 否 使用者的電子郵件。
exp 是 權杖的過期時間。最多從現在起 24 小時。

顯示編輯器

<iframe
  src="https://embed.bannerify.co/emb_xxx?token=TOKEN"
  style="width: 100%; height: 800px; border: 0"
  allow="clipboard-write"
></iframe>

在網址後面加上 &templateId=tpl_xxx,就能直接開啟某一份設計。

使用 SDK

SDK 會替你加入 iframe、告訴你的頁面使用者做了什麼,並讓你的頁面控制編輯器。

npm install @bannerify/embed
import { createBannerifyEmbed } from "@bannerify/embed"

const embed = createBannerifyEmbed({
  container: document.getElementById("editor"),
  embedId: "emb_xxx",
  token, // signed by your server
})

embed.on("template:update", ({ template }) => {
  console.log("Saved", template.id)
})

在 React 中,請安裝 @bannerify/embed-react 並使用元件。ref 可以控制編輯器。

npm install @bannerify/embed-react
import { BannerifyEmbed, type BannerifyEmbedHandle } from "@bannerify/embed-react"

const editor = useRef<BannerifyEmbedHandle>(null)

<BannerifyEmbed
  ref={editor}
  embedId="emb_xxx"
  token={token}
  style={{ height: 800 }}
  onDownload={({ fileName, content }) => upload(fileName, content)}
/>

事件

事件 React 屬性 資料
ready onReady { user }。從這時起,編輯器會接受指令。
template:open onTemplateOpen { template, canEdit }。對於你工作區的範本,canEdit 為 false。
template:close onTemplateClose { templateId }
template:create onTemplateCreate { template },用於新的設計或副本。
template:update onTemplateUpdate { template },在儲存或重新命名之後。
template:delete onTemplateDelete { templateId }
download onDownload { templateId, format, fileName, content }。content 是檔案的資料網址。
error onError { message },在編輯器無法開啟時。
asset:request onAssetRequest { requestId, type }。請見素材選擇器。

template 有 id、name、width、height 和 updatedAt。

指令

每個指令都會等待 ready,並回傳 Promise。

指令 結果
openTemplate(templateId) { template }。開啟使用者的設計,或你工作區的範本。
closeTemplate() 回到設計清單。
setModifications([{ name, text, color, src, qrcode, barcode, visible }]) { changed }。像 API 的 modification 一樣,依名稱變更已開啟設計中的圖層。
save() { template }。儲存已開啟的設計。
requestContent(format) { templateId, content }。把已開啟的設計繪製成 png、jpeg、webp 或 pdf。

你工作區的範本是唯讀的,所以 setModifications 和 save 會以 “Make a copy of this template to change it” 失敗。

每次 requestContent 都會計為你工作區的一次生成,就像在編輯器中下載,或用 API 繪製一樣。當工作區用完所有生成次數時,下載會在編輯器中顯示錯誤,而 requestContent 也會因該錯誤而失敗。

素材選擇器

在 Enterprise 方案中,當使用者新增圖片或挑選顏色時,你的頁面可以顯示自己的素材庫。請在 Asset picker 底下開啟 Images from your app 或 Colors from your app。這樣 Media 面板就會顯示帶有你應用程式名稱的 Choose from,顏色選擇器也會多出一個色票按鈕。使用者仍然可以上傳自己的檔案。

const embed = createBannerifyEmbed({
  container,
  embedId: "emb_xxx",
  token,
  onAssetRequest: async ({ type }) => {
    if (type === "image") {
      const photo = await openMyMediaLibrary() // your own UI
      return photo ? { url: photo.url, fileName: photo.name } : null
    }
    const hex = await openMyBrandColors()
    return hex ? { value: hex } : null
  },
})

當使用者關閉你的選擇器時,請回傳 null。Bannerify 會從 https 網址下載圖片,並複製到使用者的上傳項目中,所以之後網址就算失效也沒關係。圖片可以是 PNG、JPEG、WebP 或 SVG,最大 5 MB。在 React 中,請把相同的函式傳給 onAssetRequest。

不使用 SDK

編輯器透過 postMessage 與你的頁面溝通。它會把 { source: "bannerify-embed", type, data } 傳送給包住它的頁面,並且只接受來自該頁面的 { source: "bannerify-host", type, requestId, data }。它會用 { source: "bannerify-embed", type: "response", requestId, data } 回應每個指令;發生錯誤時,則以 error 取代 data。指令類型有 open-template、close-template、set-modifications、save、request-content 和 asset-response。對每個 asset:request 事件,請用 asset-response 和資料 { requestId, asset } 回應,其中 asset 是 { url, fileName }、{ value } 或 null。

你的使用者可以做什麼

  • 以常見尺寸建立設計,或複製你工作區的範本。
  • 編輯文字、圖片、形狀、QR 碼,以及編輯器中的其他圖層。
  • 上傳自己的圖片。
  • 把設計下載為 PNG、JPEG、WebP 或 PDF。每次下載都計為你工作區的一次生成。

你可以在 Permissions 底下分別開啟或關閉這些功能。在 Appearance 底下,可以設定編輯器頂端的名稱和標誌,以及主要按鈕的強調色。

繪製使用者的設計

用範本清單的 embedUserId 參數列出某位使用者的設計,然後像任何範本一樣繪製它們。

curl "https://api.bannerify.co/v1/templates?apiKey=bnfy_xxx&embedUserId=user_123"

你的使用者的範本不會顯示在儀表板的範本清單中。

Webhook

在 Webhook 底下新增一個網址,當使用者建立、變更或刪除設計時,你的伺服器就會收到 POST。請用它來維護你自己的紀錄,因為 SDK 的事件只會傳到已開啟的頁面。

{
  "id": "eev_01J9X...",
  "type": "template.create",
  "createdAt": "2026-10-19T08:00:00.000Z",
  "embedId": "emb_xxx",
  "user": { "id": "user_123" },
  "template": { "id": "tpl_xxx", "name": "Summer sale", "width": 1080, "height": 1080 }
}
type 時機
template.create 使用者開始新的設計,或複製範本。
template.update 使用者儲存或重新命名設計。
template.delete 使用者刪除設計。
test 你點選 Send test event。user 和 template 為 null。

對於沒有 sub 的權杖,user 為 null。請在 10 秒內以 2xx 狀態碼回應。失敗的傳送會在 1、2、4、8、16 和 32 分鐘後重試。相同的事件一律有相同的 id,所以請略過已經處理過的 id。

檢查簽章

每個請求都有 Bannerify-Signature 標頭:t=<unix seconds>,v1=<signature>。簽章是用 webhook 密鑰,對 <t>.<raw body> 計算 HMAC-SHA256 後的十六進位值。

import { createHmac, timingSafeEqual } from "node:crypto"

const verify = (rawBody: string, header: string, secret: string) => {
  const { t, v1 } = Object.fromEntries(header.split(",").map((part) => part.split("=")))
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false
  const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex")
  return v1.length === expected.length && timingSafeEqual(Buffer.from(v1), Buffer.from(expected))
}

請在解析之前先讀取原始本文:解析後再序列化的本文,位元組可能會不一樣。

分析

在 Enterprise 方案中,Embed 頁面的 Analytics 區段會顯示你的使用者在過去 7、30 或 90 天內如何使用編輯器:使用者、工作階段、建立的設計和下載次數、每日的工作階段數、開啟編輯器的網站,以及最活躍的使用者。工作階段是指編輯器的一次載入。日期以 UTC 計算。

輪替簽署密鑰

當密鑰外洩時,請點選 Rotate secret。用舊密鑰簽署的權杖會立刻失效,所以請先更新你的伺服器。

疑難排解

訊息 處理方式
The embed token is not valid 請用目前的簽署密鑰簽署權杖,alg 使用 HS256,並加入 exp 宣告。
This embed is turned off 請在儀表板中開啟嵌入功能。
This app reached its limit of editor users 每個 sub 計為一位使用者。請升級到 Enterprise 以取得更多使用者名額。
This app used all its generations for this month 下載會計為你工作區的生成次數。請等到每月 1 日重設,或變更你的方案。
頁面沒有顯示編輯器 請在 Allowed domains 底下加入該頁面的來源。