← All posts
Guide

How to Implement a LINE MINI App Custom Action Button

A LINE MINI App custom action button is a button in the app body that opens LINE’s share target picker. After the user chooses friends, groups, or chats, liff.shareTargetPicker() sends a developer-created share message on the user’s behalf. Use LINE’s prescribed Flex Message layout, point detail buttons to permanent MINI App links, and treat cancellation separately from success or failure.

Key takeaways

  • The built-in header action button shares the current page automatically; a custom action button lets the app control the share-message content.
  • Both unverified and verified LINE MINI Apps can use a custom action button. It is not a production service-message permission.
  • The user must be logged in, and share target picker must be enabled in LINE Developers Console.
  • LINE’s custom format uses one Flex Message bubble, not a carousel, with a required title, button area, and branded footer.
  • A resolved Promise without a result means the user cancelled; only { status: "success" } confirms that the share completed.

What a LINE MINI App custom action button actually does

LINE’s official custom action button guide distinguishes two share controls. The built-in action button lives in the header, is displayed by LINE, and shares the page currently open. Its behavior and share content cannot be customized. A custom action button lives in your MINI App body and launches the target picker with content your application assembles.

This is a user-initiated share flow, not a server notification:

FeatureCustom action buttonService messageMessaging API message
InitiatorUser taps a button and selects recipientsServer follows up on an eligible MINI App actionOfficial Account bot replies or sends to eligible recipients
Main APIliff.shareTargetPicker() in the MINI AppService Message API on the serverMessaging API on the server
Sender shown to recipientThe sharing userRegional LINE MINI App notice chatLINE Official Account
Content controlPrescribed custom Flex Message formatReviewed service-message templateSupported Messaging API message objects
Verification gateAvailable to unverified and verified MINI AppsVerified MINI App required for productionMessaging API channel and Official Account rules apply

If verification or notifications are the real question, use the verified-versus-unverified MINI App guide and the service message vs Messaging API comparison. The custom button does not grant either messaging capability.

LINE MINI App custom action button implementation checklist

1. Enable and test the share target picker

Initialize LIFF normally, confirm the user is logged in, and enable share target picker in LINE Developers Console. LINE’s LIFF API reference states that both conditions are required.

Before enabling the button, check liff.isApiAvailable("shareTargetPicker"). In a smartphone external browser, the picker also requires an SSO login session; auto login alone may lead to the email login screen instead of the picker. Test inside the LIFF browser and in the external-browser path your users actually follow.

2. Build the prescribed Flex Message, not an arbitrary card

LINE requires a Flex Message bubble for this custom share format and explicitly excludes a carousel. The card must have a concise title, either a subtitle or detail list, a button area, and a branded footer. Depending on the chosen standard or image-list layout, follow the documented component properties rather than treating the example as a general Flex Message canvas.

The button area can contain up to three buttons. At least one must open a detail page for the shared content. The footer identifies the LINE MINI App and links back to its top page.

Do not put the ordinary web endpoint URL into a button that should reopen a specific MINI App screen. LINE documents the formula as:

LIFF URL + (LINE MINI App page URL - endpoint URL) = permanent link

For example, if the LIFF URL is https://miniapp.line.me/123456-abcdefg, the endpoint is https://example.com, and the page is https://example.com/orders/42?from=share, the permanent link is:

https://miniapp.line.me/123456-abcdefg/orders/42?from=share

LINE’s permanent-link guide allows paths, query strings, and fragments. Test the exact link in LINE, including authentication, expired records, and deleted content. The header’s built-in action button generates its own permanent link; custom message buttons do not.

4. Call the picker from an explicit user action

Keep the message small and derive its text and links from a server-authorized record, not untrusted query parameters. A minimal control flow looks like this:

async function shareOrder(order) {
  if (!liff.isApiAvailable("shareTargetPicker")) {
    return { outcome: "unavailable" };
  }

  try {
    const result = await liff.shareTargetPicker([
      {
        type: "flex",
        altText: `Order ${order.reference}`,
        contents: buildApprovedBubble(order),
      },
    ]);

    return result?.status === "success"
      ? { outcome: "shared" }
      : { outcome: "cancelled" };
  } catch (error) {
    return { outcome: "failed", error };
  }
}

The helper above is an implementation pattern, not a complete LINE layout. buildApprovedBubble() must return the prescribed Bubble structure from the current LINE guide.

5. Separate success, cancellation, and pre-display errors

The LIFF Promise has three important outcomes:

OutcomeAPI behaviorApplication behavior
SentResolves with { status: "success" }Show a restrained success state; do not claim a recipient opened the link
CancelledResolves without a result objectReturn to the page without an error alert
Failed before picker displayRejects with LiffErrorLog a safe error code and offer retry or the built-in header share path

LINE does not provide the number of people who received a target-picker share. Do not manufacture recipient counts, delivery analytics, or conversion events from the resolved Promise.

6. Run a device-level acceptance matrix

At minimum, test logged-in and logged-out states, LIFF browser and smartphone external browser, picker enabled and disabled, single and multiple recipients, cancellation, a valid deep link, an expired deep link, and long localized content. Also verify that OpenChat is not presented as a supported target; the API reference lists groups, friends, and chats, excluding OpenChat.

Where UnifyPort fits

UnifyPort does not implement liff.shareTargetPicker(), create the LINE target picker, validate the custom Flex Message layout, or provide share-recipient analytics. Those belong to the official LINE MINI App and LIFF flow.

UnifyPort fits after a different user action: an ordinary customer sends a message to a connected LINE account. Supported messages can arrive as normalized message.received events. When a webhook endpoint has a signing_secret, deliveries include X-Device-Timestamp and X-Device-Signature for HMAC-SHA256 verification.

That boundary is useful when a shared MINI App page leads to a later support conversation. Keep the share event, order or campaign ID, and inbound conversation as separate records that your application correlates. Review the LINE authorization guide and provider message-support matrix before relying on an inbound or reply capability.

Limitations and trade-offs

  • Use the built-in header action button when sharing the current page is enough; it is simpler and automatically produces the page’s permanent link.
  • Use the custom button only when the share message needs a guided, LINE-compliant card. It adds layout, link, login, and device-testing work.
  • A custom action button cannot send silently, choose recipients automatically, prove delivery, or expose the recipient count.
  • It does not replace service messages, Messaging API push messages, an Official Account, or customer-support intake.

FAQ

Can an unverified LINE MINI App use a custom action button?

Yes. LINE’s current custom-features matrix lists custom action buttons for both unverified and verified MINI Apps. Production service messages remain a separate verified-only feature.

What is the difference between the built-in and custom action buttons?

The built-in header button shares the page currently open and its content cannot be customized. A custom body button calls liff.shareTargetPicker() with a developer-created, guideline-compliant share message.

Does liff.shareTargetPicker() tell me how many people received the message?

No. LINE says it neither collects nor provides the recipient count for target-picker shares. A success result confirms the share action, not views or conversions.

Why did the Promise resolve without status: "success"?

If the user closes the picker before sending, the Promise resolves without a result object. Treat that as cancellation, not as an API error.

Use a permanent LINE MINI App link for any page other than the top page. It preserves the MINI App context and can include a path, query string, or fragment.

Next step

Implement and validate the card against LINE’s official custom action button guide. If the separate requirement is receiving ordinary LINE customer messages, start with the UnifyPort LINE authorization guide.

Sources

Official LINE sources checked on August 8, 2026: