Chapter 2: Perfectly Integrating LIFF with Line Login in React
In the previous chapter, we obtained the sacred LIFF ID. Now we'll return to our React + Vite project to install Line's SDK.
Master this step, and your web app will possess the "login-on-open" black magic technology.
1. Install the @line/liff Package
Run in terminal:
npm install @line/liff
2. Create a LIFF Initialization Hook (useLiff.ts)
Don't scatter LIFF logic across components! We'll write a custom Hook to centrally manage Line's login state.
// src/hooks/useLiff.ts
import { useEffect, useState } from 'react';
import liff from '@line/liff';
export function useLiff() {
const [profile, setProfile] = useState<any>(null);
const [error, setError] = useState<string | null>(null);
const [isReady, setIsReady] = useState(false);
useEffect(() => {
// Insert the LIFF ID you obtained in the previous chapter here
liff.init({ liffId: import.meta.env.VITE_LIFF_ID })
.then(() => {
setIsReady(true);
// Check if opened inside Line or already logged in
if (liff.isLoggedIn()) {
liff.getProfile().then((p) => {
setProfile(p);
}).catch((err) => {
console.error('Failed to get Profile', err);
setError(err.toString());
});
} else {
// If not logged in, proactively request Line Login
liff.login();
}
})
.catch((err) => {
console.error('LIFF initialization failed', err);
setError(err.toString());
});
}, []);
return { profile, error, isReady, liff };
}
3. Use User Info in the Punch Card Page
Now simply call this Hook in your punch card component, and you'll instantly get the employee's name and avatar - no need for them to enter credentials!
// src/components/PunchCard.tsx
import { useLiff } from '../hooks/useLiff';
export function PunchCard() {
const { profile, isReady, liff } = useLiff();
if (!isReady) return <div>Loading Line system...</div>;
if (!profile) return <div>Please login with Line first...</div>;
const handlePunch = async () => {
// Get a secure Access Token to send to our FastAPI backend
const accessToken = liff.getAccessToken();
await fetch('https://api.yourdomain.com/punch', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ action: 'check-in' })
});
alert('Punch successful!');
// After punching, directly close the Line window! Ultimate VIP experience!
liff.closeWindow();
};
return (
<div className="p-4 bg-white rounded-xl shadow-md flex flex-col items-center">
<img src={profile.pictureUrl} alt="avatar" className="w-20 h-20 rounded-full mb-4" />
<h2 className="text-xl font-bold mb-6">Hello, {profile.displayName}</h2>
<button
onClick={handlePunch}
className="w-full bg-green-500 text-white font-bold py-4 rounded-lg text-lg"
>
Clock In
</button>
</div>
);
}
4. Why This Architecture is So Powerful?
Look closely at the liff.getAccessToken() line.
This is LIFF's most powerful feature: it generates a "key" that can only be produced by "this specific phone's Line app". We send it to our backend (FastAPI), which can verify this key with Line's servers to confirm "this person definitely isn't cheating by having someone else punch for them"!
This is the confidence booster for SaaS projects. In the next chapter, we'll implement this key verification mechanism in our FastAPI backend!