🙌
初めての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連携で自動デプロイ
環境セットアップ
必要な前提条件
- Node.js (v18以上推奨)
- npm または yarn
- LINE Developersアカウント
- 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コンソールへの登録
- LINE Developersにアクセス
- プロバイダーを作成(または既存のものを選択)
- 新規チャネルを作成(種類: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
デプロイ後
- 発行されたURL(
https://your-app.pages.dev)を取得 - LINE Developers → LIFFエンドポイントURLを更新
Discussion