跳至主要內容
技術筆記·2026年3月1日·12 分鐘閱讀

LINE LIFF 開發踩坑紀錄:那些文件沒告訴你的事

作者:Ken

為什麼要寫這篇?

LINE LIFF(LINE Front-end Framework)是台灣開發者常用的工具,但官方文件經常語焉不詳,很多行為要自己踩過才知道。這篇整理了我在多個專案中遇到的坑,希望能幫你少走一些冤枉路。

LIFF 初始化的時機問題

liff.init() 看似簡單,但在 SPA 框架中很容易踩坑。最常見的問題是在元件掛載前就嘗試呼叫 LIFF API,導致 SDK not initialized 錯誤。建議的做法是在 App 最頂層初始化,用 state 追蹤初始化狀態,子元件透過 Context 取得 LIFF 實例。

另一個坑:在外部瀏覽器中 liff.init() 不會自動登入,需要額外呼叫 liff.login()

// 建議的初始化模式
const [isReady, setIsReady] = useState(false);
 
useEffect(() => {
  liff.init({ liffId: "YOUR_LIFF_ID" }).then(() => {
    if (!liff.isLoggedIn()) {
      liff.login();
    }
    setIsReady(true);
  });
}, []);

iOS 與 Android 的行為差異

這是最讓人崩潰的部分。同樣的程式碼在 iOS 和 Android 上可能有完全不同的行為。例如:

  • iOS 的 LIFF 瀏覽器不支援 window.open()
  • Android 上 liff.closeWindow() 有時不會真的關閉視窗
  • 相機權限的請求時機在兩個平台上不同

我的建議是:永遠在兩個平台上都測試,不要假設行為一致。

ShareTargetPicker 的各種限制

ShareTargetPicker 是 LIFF 中最常用也最多坑的功能。首先,它只能在 LIFF 瀏覽器中使用(外部瀏覽器不行)。其次,Flex Message 的格式驗證非常嚴格,官方的 Flex Message Simulator 模擬的結果和實際送出的有時會不同。

最後,ShareTargetPicker 在 iOS 上的回傳值不可靠,不要依賴它判斷用戶是否真的分享了。

// ShareTargetPicker 使用注意
if (liff.isApiAvailable("shareTargetPicker")) {
  const result = await liff.shareTargetPicker([flexMessage]);
  // ⚠️ iOS 上 result 可能不準確
  // 建議用 server-side webhook 驗證
}

實用建議總結

經過多次踩坑,我整理出幾個實用建議:

  • 永遠使用最新版 LIFF SDK
  • 在 App 層級初始化並用 Context 傳遞
  • 為 iOS/Android 差異寫條件判斷
  • ShareTargetPicker 的結果用 server-side 驗證
  • 善用 liff.getOS()liff.isInClient() 做環境判斷

最重要的是:不要完全信任官方文件,實際測試才是王道。

ACCEPTING_PROJECTS

有想法想討論?

不管是明確的需求還是模糊的想法,都歡迎聊聊。我們會先幫你釐清方向,再決定怎麼做。