# Developing a LIFF app
A LIFF app is a web app based on HTML and JavaScript. Here, we'll explain the process of developing a LIFF app and processes specific to building LIFF apps.
- Setting the title of the LIFF app
- Integrating the LIFF SDK with the LIFF app
- Calling the LIFF API
- Initializing the LIFF app
- Getting the environment in which the LIFF app is running
- Performing a login process
- Opening a URL
- Opening the 2D code reader
- Getting the screen type from which the LIFF app was launched
- Get user profile
- Getting the friendship status between the user and the LINE Official Account
- Getting the permanent link of any page in the LIFF app
- Sending messages to the current chat screen
- Sending messages to a user's friend (share target picker)
- Closing the LIFF app
- Setting the OGP tags
- When opening the external site that isn't a non-LIFF app (LINE version 12.13.0 or later only)
- Next steps
# Setting the title of the LIFF app
The title of the LIFF app will appear in the title bar of the LIFF app.
Specify the name of the LIFF app in the <title>
element of the HTML source of the web app.
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The title</title>
# Integrating the LIFF SDK with the LIFF app
You can embed the LIFF SDK in the LIFF app using these methods:
# Specify the CDN path
To use the functions of the LIFF SDK, specify the URL of the LIFF SDK in the src
attribute of the <script>
element of the LIFF app's HTML source.
We prepare these two types of CDN paths for LIFF. Specify the CDN path that suits your purpose.
CDN path | Description |
---|---|
CDN edge path | This is a CDN path that contains only the MAJOR version. Use this CDN path if you want to always be up-to-date with the latest LIFF features. You only need to update your URL when a new MAJOR version is released. e.g.: https://static.line-scdn.net/liff/edge/2/sdk.js |
CDN fixed path | This is a CDN path that contains up to the PATCH version. Use this CDN path if you want to use the LIFF features of a specific version. You can continue to use the specified PATCH version as long as you don't update the LIFF app. Update your URL only when you want to implement our new features, security updates, and bug fixes. It's not updated automatically and isn't affected by the LIFF SDK update. e.g.: https://static.line-scdn.net/liff/edge/versions/2.22.3/sdk.js |
Developers using the CDN fixed path will need to decide when to update their LIFF app. You can evaluate each update we provide by frequently checking the Release notes in the LIFF documentation and decide if the update is right for you.
Example of specifying a CDN fixed path:
<script charset="utf-8" src="https://static.line-scdn.net/liff/edge/versions/2.22.3/sdk.js"></script>
The LIFF SDK is written in UTF-8, so if your HTML source uses a character encoding different than UTF-8, make sure you also specify charset="utf-8"
.
# Use the npm package
The LIFF SDK is available as an npm package. You can use npm to install the LIFF SDK.
It is the developer's responsibility to use an appropriate SDK version. To keep your SDK version up to date, check the LIFF release notes on a regular basis, and update your local SDK frequently. For more information about LIFF's versioning policy, see LIFF SDK (sdk.js) update policy.
Node.js polyfill has been removed from webpack v5. (opens new window) Accordingly, if you use the npm version of LIFF v2.16.0 or earlier in a project using webpack v5, you will get a build error. For more information, see the news from October 26, 2021, LIFF v2.16.1 released.
To install the LIFF SDK via npm and import it into your app, follow these steps:
Run this command in your terminal to install the LIFF SDK via npm:
$ npm install --save @line/liff
Alternatively, you can run this command in your terminal to install the LIFF SDK via Yarn:
$ yarn add @line/liff
Import the SDK into your app
Include the following code in your JavaScript or TypeScript file:
import liff from '@line/liff'; liff.init({ liffId: '1234567890-AbcdEfgh', // Use own liffId });
Type definitions for TypeScript are already included in the
@line/liff
package.Do not delcare or modify window.liffFor backward compatibility, don't declare or modify the global LIFF instance
window.liff
. Declaring or modifying window.liff may cause malfunctioning of the LINE app.
Related page: https://www.npmjs.com/package/@line/liff (opens new window)
Using the pluggable SDK reduces the LIFF SDK file size. For more information, see Pluggable SDK.
# Calling the LIFF API
You can do these things after integrating the LIFF SDK.
- Initializing the LIFF app
- Getting the environment in which the LIFF app is running
- Performing a login process
- Opening a URL
- Opening the 2D code reader
- Getting the screen type from which the LIFF app was launched
- Getting the user's profile
- Getting the friendship status between the user and the LINE Official Account
- Getting a permanent link for the current page
- Sending messages to the current chat screen
- Sending messages to a user's friend (share target picker)
- Closing the LIFF app
# Initializing the LIFF app
The liff.init()
method initializes the LIFF app and enables you to call the other methods of the LIFF SDK from the LIFF app.
When you access a LIFF URL or perform a transition between LIFF apps, the URL may be given query parameters that begin with liff.*
.
e.g.
liff.state
(indicates additional information specified in LIFF URL)liff.referrer
(indicates where the referrer came from when transitioning between LIFF apps. For more information, see Get URL from before LIFF-to-LIFF transition)
The above query parameters are given by the SDK so that LIFF apps can function properly.
When you independently alter the above query parameters, proper opening of the LIFF app and a transition between LIFF apps may not be guaranteed. Implement your app so that the liff.*
query parameter is altered after liff.init()
is resolved.
This property or methods are available even before the liff.init()
method is executed.
You can get the environment in which the LIFF app is running before initializing the LIFF app, or close the LIFF app when the LIFF app initialization fails.
- liff.ready
- liff.getOS()
- liff.getLanguage()
- liff.getVersion()
- liff.getLineVersion()
- liff.isInClient()
- liff.closeWindow()
- liff.use()
- liff.i18n.setLang()
To use the liff.closeWindow()
method before the initialization of the LIFF app by liff.init()
has finished, your LIFF SDK version must be v2.4.0 or later.
By specifying true
in the withLoginOnExternalBrowser
property of the config
object of the liff.init()
method, the liff.login()
method can be executed automatically when the LIFF app is initialized in external browsers.
liff.init({
liffId: '1234567890-AbcdEfgh', // Use own liffId
withLoginOnExternalBrowser: true, // Enable automatic login process
}).then(() => {
// Start to use liff's api
});
liffId
needs a specified LIFF app ID, which you can get by adding the LIFF app to your channel. For more information, see Adding a LIFF app to your channel.
liff.init({
liffId: '1234567890-AbcdEfgh', // Use own liffId
})
.then(() => {
// start to use LIFF's api
})
.catch((err) => {
console.log(err);
});
Also, with liff.ready
, you can get the Promise
object that resolves when you run liff.init()
for the first time after starting the LIFF app.
For more information, see the liff.init() and liff.ready sections in the LIFF v2 API reference.
The
liff.init()
method performs initialization processing based on information such asliff.state
andaccess_token=xxx
given to the primary redirect URL. If your endpoint URL includes a query parameter or path, to properly initialize the LIFF app, execute theliff.init()
method once for both the primary redirect URL and the secondary redirect URL. For more information, see Behaviors from accessing the LIFF URL to opening the LIFF app.Don't change the URL during server or front-end processing before the
Promise
object returned by theliff.init()
method is resolved. If you change the URL, it will return 'INIT_FAILED' and the LIFF app can't be opened. For example, if you perform redirects usinglocation.replace()
after runningliff.init()
, design it so that the screen transitions after thePromise
object is resolved.liff.init({ liffId: '1234567890-AbcdEfgh', // Use own liffId }).then(() => { // Redirect to another page after the returned Promise object has been resolved window.location.replace('https://liff.line.me/1234567890-AbcdEfgh/path'); });
The primary redirect URL containing
liff.state
will be redirected to the secondary redirect URL whenliff.init()
is executed. Don't send the URL information to an external logging tool such as Google Analytics, as the primary redirect URL beforeliff.init()
is executed contains credential information such as the user's access token.
Note that in LIFF v2.11.0 or later, credential information is excluded from URLs whenliff.init()
is resolved. Therefore, you can prevent leaking credential information by sending the page view in thethen()
method as follows. If you want to use logging tools, we recommend that you upgrade your LIFF app to v2.11.0 or later. For more information about the updates in LIFF v2.11.0, see Release Notes in the LIFF documentation.liff.init({ liffId: '1234567890-AbcdEfgh', // Use own liffId }).then(() => { ga('send', 'pageview'); });
# To use LINE Login in an external browser
To use LINE Login in an external browser, call the liff.init()
method twice as shown below.
Call the
liff.init()
method after loading the LIFF SDK.Call the
liff.login()
method. Once the processing of the authentication page and the authorization screen is complete, you will be redirected to the LIFF app (redirectUri
). Call theliff.init()
method again.If an error occurs during the processing of the
liff.init()
method, or if the user cancels authorization at the time of login,errorCallback
will be executed.
The behavior of LINE Login authorization requests within the LIFF browser isn't guaranteed. Also, when opening LIFF apps from an external browser or LINE's in-app browser, make sure to use the liff.login()
method for the login process, not the authorization requests with LINE Login.
# Getting the environment in which the LIFF app is running
Call the liff.isInClient()
method and the liff.getOS()
method to get the environment in which the LIFF app is running.
// print the environment in which the LIFF app is running
console.log(liff.getLanguage());
console.log(liff.getVersion());
console.log(liff.isInClient());
console.log(liff.isLoggedIn());
console.log(liff.getOS());
console.log(liff.getLineVersion());
For more information, see each method in the LIFF API reference.
- liff.getLanguage()
- liff.getVersion()
- liff.isInClient()
- liff.isLoggedIn()
- liff.getOS()
- liff.getLineVersion()
# Performing a login process
Call the liff.login()
method to perform the login process for both the LINE's in-app browser and external browsers.
You can't use liff.login()
in a LIFF browser, as it's automatically executed when liff.init()
is executed.
If you've specified true
in the withLoginOnExternalBrowser
property of the liff.init()
method, the liff.login()
method will be automatically executed when you initialize your LIFF app, even in external browsers. For more information, see liff.init() in the LIFF API reference.
// login call, only when external browser or LINE's in-app browser is used
if (!liff.isLoggedIn()) {
liff.login();
}
You can also call the liff.logout()
method to log out.
// logout call only when external browse or LINE's in-app browser is used
if (liff.isLoggedIn()) {
liff.logout();
window.location.reload();
}
For more information, see liff.login() and liff.logout() in the LIFF v2 API reference.
# Opening a URL
The liff.openWindow()
method opens the specified URL in LINE's in-app browser or an external browser.
The following code opens https://line.me
in an external browser.
// openWindow call
liff.openWindow({
url: 'https://line.me',
external: true,
});
For more information, see liff.openWindow() in the LIFF API reference.
# Opening the 2D code reader
Call the liff.scanCodeV2()
method to launch a 2D code reader, and get the string read by the user.
// scanCodeV2 call
liff.scanCodeV2()
.then((result) => {
// e.g. result = { value: 'Hello LIFF app!' }
})
.catch((err) => {
console.log(err);
});
For more information, see liff.scanCodeV2() in the LIFF API reference.
The traditional liff.scanCode()
method has been deprecated. We recommend using the liff.scanCodeV2()
method for implementing a 2D code reader.
The liff.scanCodeV2()
method works in the following environments:
- iOS: iOS 14.3 or later, LINE for iOS version 11.7.0 or later
- Android: LINE version 11.7.0 or later
- External browser: Web browsers that support WebRTC API (opens new window)
OS | Version | LINE app version | External browser | |
---|---|---|---|---|
10.17.0-11.6.x | 11.7.0 or later | |||
iOS | 11-14.2 | ❌ | ❌ | ✅ *1 |
14.3 or later | ❌ | ✅ *2 | ✅ *1 | |
Android | All versions | ❌ | ✅ *2 | ✅ *1 |
PC | All versions | ❌ | ❌ | ✅ *1 |
*1 You can only use web browsers that support WebRTC API (opens new window).
*2 Only available when the screen size of the LIFF browser is Full
. For details, see Size of the LIFF browser in the LIFF documentation.
When Adding a LIFF app to your channel, turn on Scan QR. The Scan QR setting can be updated from the LIFF tab on the LINE Developers Console, even after adding a LIFF app to your channel.
# Getting the screen type from which the LIFF app was launched
Execute the liff.getContext()
method to get a value that specifies the screen type (1-on-1 chat, group chat, multi-person chat, or external browser) from which the LIFF app is launched.
const context = liff.getContext();
console.log(context);
// {"type": "utou", "userId": "U70e153189a29f1188b045366285346bc", "viewType": "full", "accessTokenHash": "ArIXhlwQMAZyW7SDHm7L2g", "availability": {"shareTargetPicker": {"permission": true, "minVer": "10.3.0"}, "multipleLiffTransition": {"permission": true, "minVer": "10.18.0"}}}
For more information, see liff.getContext() in the LIFF v2 API reference.
# Get user profile
There are two ways to get a user's profile through getting an ID token in the LIFF app.
Use the method for your intended purpose.
When adding a LIFF app to your channel, select the openid
scope. You can't get the ID tokens if you don't select the scope, or the users don't grant permission. The scope selections can be changed in the LIFF tab of the LINE Developers Console even after adding the LIFF app.
To get the email addresses of users, select the email
scope when adding a LIFF app to your channel. You will get the email address once the user grants permission. The scope selections can be changed in the LIFF tab of the LINE Developers Console even after adding the LIFF app.
# Send user data to the server
When the LIFF app sends user data to the server, it sends the access token or ID token obtained via this method. For more information, see Using user data in LIFF apps and servers in the LIFF documentation.
Execute the
liff.getAccessToken()
method to get the access token of the current user. When the user closes the LIFF app, the access token will be revoked even if it hasn't expired.// get access token if (!liff.isLoggedIn() && !liff.isInClient()) { window.alert('To get an access token, you need to be logged in. Tap the "login" button below and try again.'); } else { const accessToken = liff.getAccessToken(); console.log(accessToken); }
For more information, see liff.getAccessToken() in the LIFF API reference.
Execute the
liff.getIDToken()
method to get the raw ID token of the current user.liff.init(() => { const idToken = liff.getIDToken(); console.log(idToken); // print raw idToken object });
For more information, see liff.getIDToken() in the LIFF API reference.
# Display user data to the LIFF app
Execute the liff.getDecodedIDToken()
method to get the profile information and email address of the current user.
Use this API to use the user's display name in the LIFF app.
Don't send the user data obtained by liff.getDecodedIDToken()
to the server.
Send the ID token obtained with liff.getIDToken()
instead.
liff.init(() => {
const idToken = liff.getDecodedIDToken();
console.log(idToken); // print decoded idToken object
});
For more information, see liff.getDecodedIDToken() in the LIFF v2 API reference.
# Getting the friendship status between the user and the LINE Official Account
Gets the friendship status between the user and the LINE Official Account that's linked to the LINE Login channel to which the LIFF app is added.
Learn more on how to Add a LINE Official Account as a friend when logged in (add friend option) in the LINE Login documentation.
liff.getFriendship().then((data) => {
if (data.friendFlag) {
// something you want to do
}
});
Learn more from liff.getFriendship() in the LIFF v2 API reference.
When adding a LIFF app to your channel, select the profile
scope. You can't get the friendship statuses if you don't select the scope, or the users don't grant permission. The scope selections can be changed in the LIFF tab of the LINE Developers Console even after adding the LIFF app.
# Getting the permanent link of any page in the LIFF app
Execute the liff.permanentLink.createUrlBy()
method to get the permanent link of any page in the LIFF app.
// For example, if the endpoint URL of the LIFF app is https://example.com/path1?q1=v1 and its LIFF ID is 1234567890-AbcdEfgh
liff.permanentLink
.createUrlBy('https://example.com/path1?q1=v1')
.then((permanentLink) => {
// https://liff.line.me/1234567890-AbcdEfgh
console.log(permanentLink);
});
liff.permanentLink
.createUrlBy('https://example.com/path1/path2?q1=v1&q2=v2')
.then((permanentLink) => {
// https://liff.line.me/1234567890-AbcdEfgh/path2?q=2=v2
console.log(permanentLink);
});
For more information, see liff.permanentLink.createUrlBy() in the LIFF v2 API reference.
# Sending messages to the current chat screen
The liff.sendMessages()
method sends messages on behalf of the user to the chat screen where the LIFF app is opened. This feature is only available in a LIFF app launched from a one-on-one chat room. You can send up to 5 message objects in a single request.
This code sends "Hello, World!" as the user's message to the chat screen where the LIFF app is displayed.
// sendMessages call
if (!liff.isInClient()) {
window.alert('This button is unavailable as LIFF is currently being opened in an external browser.');
} else {
liff.sendMessages([
{
type: 'text',
text: 'Hello, World!',
},
])
.then(() => {
window.alert('Message sent');
})
.catch((error) => {
window.alert('Error sending message: ' + error);
});
}
For more information, see liff.sendMessages() in the LIFF v2 API reference.
# Sending messages to a user's friend (share target picker)
Execute the liff.shareTargetPicker()
method to display the target picker (screen for selecting a group or friend) and send the message created by the developer to the selected target. This message appears to your group or friends as if you had sent it.
The following code displays the target picker and sends "Hello, World!" as the user's message to the selected group or friends. If you want to confirm that the target picker can be used in the environment where the LIFF app is started, execute liff.isApiAvailable()
first.
if (liff.isApiAvailable('shareTargetPicker')) {
liff.shareTargetPicker([
{
type: 'text',
text: 'Hello, World!',
},
]);
}
For more information, see liff.isApiAvailable() and liff.shareTargetPicker() in the LIFF v2 API reference.
- To view the target picker, turn on the share target picker in the LINE Developers Console. For more information, see Using share target picker.
- When using an external browser, call
liff.login()
, complete the login process, then callliff.shareTargetPicker()
.
# Closing the LIFF app
The liff.closeWindow()
method closes the opened LIFF app.
// closeWindow call
if (!liff.isInClient()) {
window.alert('This button is unavailable as LIFF is currently being opened in an external browser.');
} else {
liff.closeWindow();
}
For more information, see liff.closeWindow() in the LIFF v2 API reference.
liff.closeWindow()
isn't guaranteed to work in an external browser.
# Setting the OGP tags
By setting an OGP tag for each page of the LIFF app, for example, you can display any title, description, or thumbnail image when sharing the URL of your LIFF app (https://liff.line.me/{liffId}
) in the LINE chat room, and so on.
These are the OGP tags supported by LIFF. For more information on OGP tags, see The Open Graph protocol (opens new window).
<html lang="ja" prefix="og: http://ogp.me/ns#">
<meta property="og:title" content="The title">
<meta property="og:type" content="`website`, `blog`, or `article`">
<meta property="og:description" content="A one to two sentence description">
<meta property="og:url" content="The URL">
<meta property="og:site_name" content="The name that represents the overall site">
<meta property="og:image" content="An image URL">
When sharing the URL of the LIFF app in the format of line://app/{liffId}
(deprecated), the OGP tag will be ignored.
# When opening the external site that isn't a non-LIFF app (LINE version 12.13.0 or later only)
In the LIFF browser on LINE version 12.13.0 or later, when opening the external site that isn't a non-LIFF app from a LIFF app opened in the LIFF browser, a popup will appear indicating that "This is an external page".
The popup will only appear when opening the external site in the same window. If the external site is opened in a different window, the popup doesn't appear.
When transitioning up to a higher level (e.g. https://example.com/
) than the endpoint URL (e.g. https://example.com/path
) itself in a LIFF app, the behavior isn't guaranteed.
# Next steps
After developing the LIFF app, deploy it on any server. Once deployed, do these things: