LIFFアプリの開発方法を完全解説!初心者でもわかるステップバイステップガイド

テックジム東京本校では、情報科目の受験対策指導やAI駆動開発コースもご用意しております。

目次

この記事でわかること

  • LIFFアプリとは何か、なぜ注目されているのか
  • 開発環境のセットアップ方法
  • LIFFアプリの作り方(Hello World〜実用機能まで)
  • よくあるエラーとその対処法
  • 本番リリースまでの流れ

1. LIFFアプリとは?基本概念を理解しよう

LIFF(Line Front-end Framework) とは、LINE株式会社が提供するWebアプリのプラットフォームです。LINEアプリ内のブラウザ(LINEブラウザ)上でWebアプリケーションを動作させることができます。

LIFFの仕組み

ユーザー
   ↓ LINEトークやリッチメニューをタップ
LINE内ブラウザ(WebView)
   ↓ LIFF URLを開く
あなたのWebアプリ(LIFFアプリ)
   ↓ LIFF SDK経由でLINEの機能を利用
LINE Platform API

LIFFアプリの最大の特徴は、LINE上でそのままWebアプリが動作するため、ユーザーが外部ブラウザに遷移せずにシームレスな体験を提供できる点です。

LIFFのバージョン

バージョン 特徴
LIFF v1(非推奨) 旧バージョン。現在はサポート終了
LIFF v2(現行) 機能が豊富。現在の標準バージョン

現在の開発はすべて LIFF v2 を使用します。


2. LIFFアプリのメリット・デメリット

✅ メリット

  • ユーザー情報の取得が容易:LINEのユーザーIDや表示名、プロフィール画像を簡単に取得できる
  • 認証が不要:LINE認証をそのまま活用できるため、ログイン機能を自前で実装する必要がない
  • LINEと密な連携:メッセージ送信やシェア機能をアプリ内から呼び出せる
  • 既存のWebスキルが活用できる:HTML / CSS / JavaScriptの知識があればすぐに開発できる
  • LINE公式アカウントとの連携:チャットボットやリッチメニューとの組み合わせで強力な体験を構築できる

❌ デメリット

  • LINE内でしか動作しない機能があるliff.sendMessages()などはLINE内ブラウザ専用
  • 外部ブラウザでの動作制限:LIFF SDKの一部機能は外部ブラウザでは利用不可
  • LINE依存:LINEのAPIポリシーや仕様変更の影響を受ける

3. 開発前に準備するもの

LIFFアプリ開発を始める前に、以下を用意しましょう。

必要なアカウント・ツール

必要なもの 説明 取得先
LINEアカウント 個人のLINEアカウント LINE公式サイト
LINE Developersアカウント 開発者登録が必要 developers.line.biz
LINE公式アカウント(任意) Messaging APIと連携する場合に必要 LINE for Business
Node.js (v18以上) 開発環境 nodejs.org
テキストエディタ VS Code推奨 code.visualstudio.com
HTTPS対応のサーバー LIFFはHTTPS必須 Vercel / Netlify / ngrok等

LINE Developersコンソールでの事前設定

  1. LINE Developersコンソール にアクセス
  2. 「プロバイダー」を作成(または既存のものを利用)
  3. 「チャネル」を作成
    • LIFFアプリのみ使う場合 → 「LINEログイン」チャネルを選択
    • Messaging APIとも連携する場合 → 「Messaging API」チャネルを選択

4. 開発環境のセットアップ

Step 1:チャネルとLIFFアプリの登録

  1. LINE Developersコンソールで「LINEログイン」チャネルを作成
  2. チャネルページの「LIFF」タブを開く
  3. 「追加」ボタンをクリック

LIFF追加時の設定項目:

設定項目 説明 推奨値
LIFFアプリ名 アプリの表示名 任意
サイズ 画面の表示サイズ Full(フルスクリーン)
エンドポイントURL アプリのURL 開発中は https://localhost:3000
Scope 取得する権限 profile / openid
ボットリンク機能 公式アカウントとの連携 任意

登録後、LIFF ID(例:1234567890-AbcDeFgh)が発行されます。これが開発で使用するIDです。

Step 2:プロジェクトの作成

# プロジェクトフォルダを作成
mkdir my-liff-app
cd my-liff-app

# package.jsonを初期化
npm init -y

# LIFF SDKをインストール
npm install @line/liff

5. LIFFアプリを実際に作ってみよう

Hello World:最もシンプルなLIFFアプリ

まず、LIFFの基本的な動作確認ができる最小構成のアプリを作成します。

ファイル構成

my-liff-app/
├── index.html
├── style.css
└── app.js

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My LIFF App</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div id="app">
    <h1>LIFFアプリへようこそ!</h1>
    <div id="profile-area">
      <img id="profile-image" src="" alt="プロフィール画像">
      <p id="display-name">読み込み中...</p>
      <p id="user-id"></p>
    </div>
    <button id="send-message-btn">メッセージを送る</button>
    <button id="close-btn">閉じる</button>
  </div>
  <script src="https://static.line-scdn.net/liff/edge/2/sdk.js"></script>
  <script src="app.js"></script>
</body>
</html>

app.js

// LIFF IDを設定(LINE Developersコンソールで取得したIDに変更してください)
const LIFF_ID = "あなたのLIFF_IDをここに入力";

// LIFFの初期化
async function initializeLiff() {
  try {
    await liff.init({ liffId: LIFF_ID });
    console.log("LIFF初期化完了");

    // ログイン状態を確認
    if (!liff.isLoggedIn()) {
      liff.login();
      return;
    }

    // プロフィール情報を取得して表示
    await displayProfile();

    // ボタンのイベント設定
    setupButtons();

  } catch (error) {
    console.error("LIFF初期化エラー:", error);
    document.getElementById("display-name").textContent = 
      `エラー: ${error.message}`;
  }
}

// プロフィール情報を表示する関数
async function displayProfile() {
  try {
    const profile = await liff.getProfile();

    document.getElementById("profile-image").src = profile.pictureUrl;
    document.getElementById("display-name").textContent = 
      `こんにちは、${profile.displayName}さん!`;
    document.getElementById("user-id").textContent = 
      `ユーザーID: ${profile.userId}`;
  } catch (error) {
    console.error("プロフィール取得エラー:", error);
  }
}

// ボタンの設定
function setupButtons() {
  // メッセージ送信ボタン
  document.getElementById("send-message-btn").addEventListener("click", async () => {
    // LINE内ブラウザでのみ動作
    if (liff.isInClient()) {
      try {
        await liff.sendMessages([
          {
            type: "text",
            text: "LIFFアプリからメッセージを送信しました!🎉"
          }
        ]);
        alert("メッセージを送信しました!");
      } catch (error) {
        console.error("メッセージ送信エラー:", error);
      }
    } else {
      alert("この機能はLINEアプリ内でのみ使用できます");
    }
  });

  // 閉じるボタン
  document.getElementById("close-btn").addEventListener("click", () => {
    liff.closeWindow();
  });
}

// アプリの起動
initializeLiff();

style.css

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Hiragino Sans", sans-serif;
  background-color: #f5f5f5;
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

#app {
  background: #fff;
  padding: 32px;
  border-radius: 16px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
  text-align: center;
  width: 90%;
  max-width: 400px;
}

h1 {
  font-size: 20px;
  color: #06C755; /* LINEのグリーン */
  margin-bottom: 24px;
}

#profile-image {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  object-fit: cover;
  margin-bottom: 12px;
}

#display-name {
  font-size: 18px;
  font-weight: bold;
  color: #333;
  margin-bottom: 8px;
}

#user-id {
  font-size: 12px;
  color: #999;
  margin-bottom: 24px;
  word-break: break-all;
}

button {
  width: 100%;
  padding: 14px;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  font-weight: bold;
  cursor: pointer;
  margin-bottom: 12px;
  transition: opacity 0.2s;
}

button:hover {
  opacity: 0.85;
}

#send-message-btn {
  background-color: #06C755;
  color: #fff;
}

#close-btn {
  background-color: #e0e0e0;
  color: #333;
}

6. LIFFのAPIを使いこなす

LIFF SDKには多彩なAPIが用意されています。主要なものを一覧で確認しましょう。

主要API一覧

初期化・認証系

API 説明 使用例
liff.init() LIFF SDKの初期化。最初に必ず呼び出す await liff.init({ liffId: "..." })
liff.isLoggedIn() ログイン状態の確認 if (!liff.isLoggedIn()) liff.login()
liff.login() ログインページへのリダイレクト liff.login()
liff.logout() ログアウト liff.logout()
liff.getAccessToken() アクセストークンの取得 const token = liff.getAccessToken()
liff.getIDToken() IDトークンの取得 const idToken = liff.getIDToken()

ユーザー情報系

// プロフィール情報を取得
const profile = await liff.getProfile();
console.log(profile.userId);       // ユーザーID
console.log(profile.displayName);  // 表示名
console.log(profile.pictureUrl);   // プロフィール画像URL
console.log(profile.statusMessage);// ステータスメッセージ

// デコードされたIDトークン(より多くの情報を含む)
const decodedIDToken = liff.getDecodedIDToken();
console.log(decodedIDToken.email); // メールアドレス(scopeに`email`が必要)

メッセージ・シェア系

// トークへのメッセージ送信(LINE内ブラウザのみ)
await liff.sendMessages([
  { type: "text", text: "テキストメッセージ" },
  {
    type: "sticker",
    packageId: "1",
    stickerId: "1"
  }
]);

// シェアターゲットピッカー(友達やグループにシェア)
if (liff.isApiAvailable("shareTargetPicker")) {
  await liff.shareTargetPicker([
    {
      type: "text",
      text: "LIFFアプリからシェアしました!"
    }
  ]);
}

環境・画面系

// LINE内ブラウザかどうかを確認
const isInClient = liff.isInClient(); // true / false

// LIFFアプリのバージョン情報
const version = liff.getVersion();

// 言語設定
const language = liff.getLanguage(); // 例:"ja"

// OSの種類
const os = liff.getOS(); // "ios" / "android" / "web"

// LIFFアプリを閉じる
liff.closeWindow();

// QRコードリーダーを開く
if (liff.isApiAvailable("scanCodeV2")) {
  const result = await liff.scanCodeV2();
  console.log(result.value); // スキャンした値
}

Vite + Reactで本格的なLIFFアプリを作る

モダンな構成でのLIFFアプリ開発例です。

# Viteでプロジェクト作成
npm create vite@latest my-liff-react-app -- --template react
cd my-liff-react-app

# 依存パッケージをインストール
npm install
npm install @line/liff
// src/App.jsx
import { useState, useEffect } from "react";
import liff from "@line/liff";

const LIFF_ID = import.meta.env.VITE_LIFF_ID;

function App() {
  const [profile, setProfile] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const initialize = async () => {
      try {
        await liff.init({ liffId: LIFF_ID });

        if (!liff.isLoggedIn()) {
          liff.login();
          return;
        }

        const userProfile = await liff.getProfile();
        setProfile(userProfile);
      } catch (err) {
        setError(err.message);
      } finally {
        setIsLoading(false);
      }
    };

    initialize();
  }, []);

  if (isLoading) return <div>読み込み中...</div>;
  if (error) return <div>エラー: {error}</div>;

  return (
    <div className="app">
      {profile && (
        <>
          <img src={profile.pictureUrl} alt="プロフィール" />
          <h2>{profile.displayName}</h2>
          <p>UID: {profile.userId}</p>
        </>
      )}
    </div>
  );
}

export default App;
# .env ファイル
VITE_LIFF_ID=あなたのLIFF_ID

7. よくあるエラーと対処法

LIFF_INIT_FAILED

原因: LIFF IDが間違っている、またはエンドポイントURLが一致していない

対処法:

// LIFF IDを正確にコピーして設定する
await liff.init({ liffId: "1234567890-AbcDeFgh" }); // ハイフン含む
  • LINE Developersコンソールでエンドポイントに登録したURLと、実際にアクセスするURLが一致しているか確認
  • http:// ではなく https:// を使用しているか確認

liff.sendMessages() がエラーになる

原因: LINE外のブラウザ(外部ブラウザ)で実行している

対処法:

if (liff.isInClient()) {
  // LINE内ブラウザの場合のみ実行
  await liff.sendMessages([...]);
} else {
  alert("この機能はLINEアプリ内でのみ利用可能です");
}

❸ プロフィール情報が取得できない

原因: Scopeに profile が設定されていない

対処法: LINE DevelopersコンソールのLIFF設定画面で、Scopeに profileopenid を追加する


❹ ローカル開発でLIFFが動かない

原因: LIFFはHTTPSが必須。localhost のHTTPでは動作しない

対処法:ngrokを使ってHTTPS化する

# ngrokのインストール(Homebrewの場合)
brew install ngrok

# ローカルサーバーを起動(例:ポート3000)
npm run dev

# 別ターミナルでngrokを起動
ngrok http 3000

表示された https://xxxx.ngrok.io のURLをLIFFのエンドポイントURLに登録する。


❺ CORSエラーが発生する

原因: バックエンドAPIのCORS設定が不足している

対処法(Node.js / Express の場合):

const cors = require("cors");
app.use(cors({
  origin: "https://your-liff-app.vercel.app",
  credentials: true,
}));

8. 本番環境へのデプロイ

Vercelへのデプロイ(推奨)

VercelはHTTPS付きの無料ホスティングが使え、LIFFアプリの本番デプロイに最適です。

# Vercel CLIをインストール
npm install -g vercel

# デプロイ
vercel

# 環境変数の設定
vercel env add VITE_LIFF_ID
  1. デプロイ後に発行されたURLをコピー(例:https://my-liff-app.vercel.app
  2. LINE DevelopersコンソールのLIFF設定でエンドポイントURLを更新
  3. LINEのトークやリッチメニューにLIFF URLを設定

LIFFのURL形式

https://liff.line.me/{LIFF_ID}

このURLをLINEのトーク・リッチメニュー・シェアに使用します。

本番リリース前のチェックリスト

  • [ ] LIFF IDが本番用のものになっているか
  • [ ] エンドポイントURLが本番のHTTPS URLになっているか
  • [ ] 必要なScopeがすべて設定されているか
  • [ ] LINE内ブラウザ・外部ブラウザ両方で動作確認済みか
  • [ ] エラーハンドリングが実装されているか
  • [ ] アクセストークンをサーバーサイドで検証しているか(セキュリティ)

9. LIFFアプリの活用事例

LIFFアプリは多様なビジネスシーンで活用されています。

📅 予約・申し込みシステム

LINEから離れずに予約が完結するため、離脱率が大幅に低下します。美容室・飲食店・医療機関など幅広い業種で活用されています。

🛒 ECサイト・カート機能

LINEのトーク経由で商品ページに誘導し、そのままカートに追加・決済まで完結させる構成が可能です。

📋 アンケート・フォーム

LINE公式アカウントからリッチメニューでLIFFフォームへ誘導。ユーザー情報が自動入力されるため、回答率が向上します。

🎟️ デジタル会員証・クーポン

ユーザーIDと紐づけた会員証やQRコードを表示。スタンプカードのデジタル化にも活用できます。

📦 注文状況確認

ECや飲食店の注文状況をリアルタイムで確認できるトラッキング画面。LINE通知と組み合わせると強力です。


10. まとめ

LIFFアプリの開発方法を一通り解説しました。要点を整理します。

ポイント 内容
LIFFとは LINEのWebアプリプラットフォーム。LINE内でWebアプリが動作する
開発言語 HTML / CSS / JavaScript(ReactやVueも使用可能)
必要な準備 LINE Developersアカウント・チャネル作成・LIFF登録
LIFF ID 開発・本番それぞれでコンソールから取得
HTTPS必須 ローカル開発はngrok、本番はVercel等を使用
主要API liff.init() / liff.getProfile() / liff.sendMessages()
注意点 一部のAPIはLINE内ブラウザ専用。liff.isInClient() で分岐する

LIFFアプリはLINEという巨大なプラットフォームを活用したWebアプリであり、正しく実装することでユーザーの利便性を大幅に高めることができます。まずはシンプルなHello Worldアプリから始め、徐々に機能を追加していきましょう。


参考リンク


    ゼロから始めるClaudeCode講座のご案内

    テックジム東京本校では「ClaudeCode」の体験講座を開催。
    「その日のうちに動かす」 をゴールに、環境構築から実践まで。
    毎週土曜日15時。参加は無料です。対面・ハンズオンだから初心者でも安心。

    らくらくPython塾 – 読むだけでマスター

    共通テスト「情報I」対策解説講座

    実践で学ぶPython速習講座

    テックジム東京本校

    格安のプログラミングスクールといえば「テックジム」。
    講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
    対面型でより早くスキル獲得、月額2万円のプログラミングスクールです。
    情報科目の受験対策指導やAI駆動開発コースもご用意しております。