🙌

初めてのLINEミニアプリ開発

に公開

目的

クーポンLINEミニアプリの開発

  • 1時間無料クーポンの発行・管理
  • ユーザー登録・管理

技術スタック

  • フロントエンド: React + TypeScript + Vite
  • LINEフロントエンドフレームワーク: LIFF (LINE Front-end Framework)
  • バックエンド: Supabase
  • データベース: PostgreSQL(Supabase)
  • ホスティング: Claude flare

技術スタックの選定理由

React + TypeScript + Vite

  • React: コンポーネントベースで保守性が高い
  • TypeScript: 型安全で大規模開発にも対応
  • Vite: 高速な開発環境と最適化されたビルド

LIFF (LINE Front-end Framework)

  • LINEアプリ内でWebアプリを動作させるための公式SDK
  • ユーザー情報の取得、メッセージ送信などLINE機能との連携が簡単
  • 認証処理がLINEログインで完結

Supabase

  • PostgreSQLベースで本格的なデータベース機能
  • リアルタイム機能、認証、ストレージを一括提供
  • 無料プランで開発開始可能
  • サーバーレスで運用コストが低い

Cloudflare Pages

  • 無料でSSL対応のホスティング
  • CDNで高速な配信
  • GitHub連携で自動デプロイ

環境セットアップ

必要な前提条件

  1. Node.js (v18以上推奨)
  2. npm または yarn
  3. LINE Developersアカウント
  4. LINE公式アカウント(ミニアプリを配信するため)

プロジェクトのセットアップ

# 依存関係のインストール
npm install

# 開発サーバーの起動(HTTPSが必要)
npm run dev:https

# ビルド
npm run build

環境変数の設定

.envファイルを作成:

# LIFF設定
VITE_LIFF_ID=your-liff-id-here

# APIエンドポイント
VITE_API_BASE_URL=https://api.your-domain.com

LINE Developersの設定

1. LINE Developersコンソールへの登録

  1. LINE Developersにアクセス
  2. プロバイダーを作成(または既存のものを選択)
  3. 新規チャネルを作成(種類:LINEミニアプリ)

2. チャネルの基本設定

チャネル名: 〇〇アプリ
チャネル説明: クーポン管理アプリ
アプリタイプ: Web app

3. LIFF(LINE Front-end Framework)の設定

LINEミニアプリはLIFFを使用して作成します。

エンドポイントURL: https://your-domain.com
スコープ: 
  - profile(必須)
  - openid(必須)
  - email(オプション)
サイズ: Full (ミニアプリは通常Full)

フロントエンド開発

LIFF初期化

src/lib/liff.ts

import liff from '@line/liff';

export const initializeLiff = async () => {
  try {
    await liff.init({ 
      liffId: import.meta.env.VITE_LIFF_ID 
    });
    
    if (!liff.isLoggedIn()) {
      liff.login();
    }
    
    return liff;
  } catch (error) {
    console.error('LIFF initialization failed', error);
    throw error;
  }
};

export { liff };

メインアプリケーション

src/App.tsx

import { useEffect, useState } from 'react';
import { initializeLiff, liff } from './lib/liff';

function App() {
  const [profile, setProfile] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const init = async () => {
      try {
        await initializeLiff();
        const userProfile = await liff.getProfile();
        setProfile(userProfile);
      } catch (err) {
        console.error(err);
      } finally {
        setLoading(false);
      }
    };
    init();
  }, []);

  if (loading) return <div>読み込み中...</div>;

  return (
    <div className="app">
      <h1>クーポンアプリ</h1>
      {profile && (
        <div>
          <img src={profile.pictureUrl} alt="Profile" />
          <h2>ようこそ、{profile.displayName}さん</h2>
        </div>
      )}
    </div>
  );
}

export default App;

よくあるエラーと修正

エラー1: ファイル参照エラー

<!-- index.html -->
<!-- ❌ 間違い -->
<script type="module" src="/src/main.ts"></script>

<!-- ✅ 正しい -->
<script type="module" src="/src/main.tsx"></script>

エラー2: DOM要素のID不一致

<!-- index.html -->
<div id="root"></div>
// main.tsx
ReactDOM.createRoot(document.getElementById('root')!).render(
  <App />
);

バックエンド開発(Supabase)

データベース設計

テーブル作成

Supabase Dashboard → SQL Editor で実行:

-- ユーザーテーブル
CREATE TABLE users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  line_user_id TEXT UNIQUE NOT NULL,
  display_name TEXT,
  picture_url TEXT,
  created_at TIMESTAMP DEFAULT NOW()
);

-- クーポンテーブル
CREATE TABLE coupons (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  title TEXT NOT NULL,
  description TEXT,
  discount_value TEXT NOT NULL,
  expiry_date DATE,
  is_active BOOLEAN DEFAULT true,
  created_at TIMESTAMP DEFAULT NOW()
);

-- クーポン使用履歴
CREATE TABLE coupon_usage (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES users(id),
  coupon_id UUID REFERENCES coupons(id),
  used_at TIMESTAMP DEFAULT NOW(),
  UNIQUE(user_id, coupon_id)
);

Supabaseクライアント初期化

src/lib/supabase.ts

import { createClient } from '@supabase/supabase-js';

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;

export const supabase = createClient(supabaseUrl, supabaseAnonKey);

デプロイ

Cloudflare Pagesへのデプロイ

ビルド設定

Framework preset: None
Build command: pnpm build
Build output directory: dist

環境変数

VITE_LIFF_ID = your-liff-id
VITE_SUPABASE_URL = your-supabase-url
VITE_SUPABASE_ANON_KEY = your-supabase-key

デプロイ後

  1. 発行されたURL(https://your-app.pages.dev)を取得
  2. LINE Developers → LIFFエンドポイントURLを更新

Discussion