LIFFブラウザとLINE内ブラウザって何が違うの？

## はじめに
業務でLIFFアプリを開発しているときに、LIFFブラウザとLINE内ブラウザの違いを理解していなかったため、泥沼にハマりました。

本記事では2つの明確な違いについてわかりやすく解説します。

## 公式サイトの解説
まずはLINE Developersの[用語集](https://developers.line.biz/ja/glossary/)の説明を参照します。

### LIFFブラウザ
> LIFFアプリ専用のブラウザ。ユーザーがLINEでLIFFのURLを開くと、LIFFブラウザでLIFFアプリが開きます。詳しくは、「LIFFブラウザ」を参照してください。


LIFFアプリを開くときにはLIFFブラウザが使われるようです。

#### LIFFブラウザ詳細
『詳しくは、「LIFFブラウザ」を参照してください』と、別ページへのリンクが示されていたので、そちらも参照します。
> LIFFブラウザはLIFFアプリ専用のブラウザです。ユーザーがLINEでLIFFのURLを開くと、LIFFブラウザでLIFFアプリが開きます。
>
> LIFFブラウザはLINE内で動作するため、LIFFアプリはユーザーにログインを促さなくてもユーザーデータにアクセスすることができます。また、LIFFブラウザはLIFFアプリを共有したり、LIFFアプリから友だちにメッセージを送るなど、LINE特有の機能を提供しています。

LIFFブラウザには固有の機能があるようです。

### LINE内ブラウザ
> LINEのアプリ内専用のWebブラウザ。LINE内ブラウザを使うとLINEアプリを閉じずにURLを開いてインターネット上のウェブアプリを閲覧することができます。

LINEアプリにとどまったままWebページを閲覧できる、ということのようです。

ただ、私の場合この解説を読んでも、ハマった泥沼から抜け出すことができませんでした。
※泥沼の詳細はページ下部の[おまけ](#おまけ)にて触れています。

## 機能的な違い
ここからは、用語の定義ではない部分から、違いについてフォーカスしていきます。

まず、2つのブラウザについて機能的に大きな違いが1点あります。
それは`liff.init()`を実行した際に、自動でログインされるか、されないかという違いです。

以下のページにその詳細が記載されています。

https://developers.line.biz/ja/docs/liff/developing-liff-apps/#login-with-line-login

一部を抜粋します。
> 外部ブラウザおよびLINE内ブラウザの場合、liff.login()メソッドを実行して、ログイン処理を行います。
> 
> 注意
LIFFブラウザの場合、liff.init()実行時に自動でログイン処理が実行されるため、liff.login()は利用できません。

つまり、
* LIFFブラウザ使用時、自動でログイン処理が実行される
* LINE内ブラウザ使用時、`liff.login()`による明示的なログインが必要

ということです。

これはかなり大きな違いです。
ログイン処理をしていないと使用できないliffのメソッドもいくつかあるためです。

## 見た目の違い
2つのブラウザは、見た目がまったく異なります。
私が過去に作成したデモアプリでその違いを確認します。

### LIFFブラウザ
LIFFブラウザの場合、ヘッダー部に
* LIFFアプリ名
* LIFFアプリのエンドポイントURL
* シェアアイコン
* 閉じるアイコン
が表示されます。

フッターはありません。
<img width='80%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/05506cec-6049-f362-6e92-52cb44de45ab.png'>

シェアアイコンをクリックすると、以下3つのメニューが表示されます。
<img width='80%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/80b25978-2ccc-03b1-5a1f-95ff80be5472.png'>

「シェア」はLINEの友達に対してアプリをシェアできる機能です。
友達はもちろん、KeepメモやVOOMへのシェアもできます。
<img width='80%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/8003db2a-5702-fa30-a99e-1873c5a937f3.png'>

「更新」は画面を再読込します。

「権限設定」はカメラ、マイクの権限について設定できます。

#### サイズの異なるLIFFブラウザ
また、これはLIFFアプリのサイズを「Full」に指定した場合の見え方です。
LIFFアプリのサイズはLINE Developersコンソールで変更できます。
「Full」のほか、「Tall」、「Compact」があります

##### Tall
画面いっぱいではなく、4分の3くらいまでをおおう形でアプリが表示されます。
LINEのトーク画面が見切れているのがわかるかと思います。
<img width='80%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/ab7bbee2-1cb8-e624-7986-41662b32322d.png'>

##### Compact
さらにアプリの表示される領域が小さくなります。
<img width='80%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/5ea03b43-533a-192d-5711-aa298967a8fe.png'>

「Tall」、「Compact」の場合にはシェアアイコンは表示されません。

### LINE内ブラウザ
同じデモアプリを今度はLINE内ブラウザで表示します。

:::note info
鋭い方は、「LIFFアプリなのにどうやってLINE内ブラウザで表示させたか」を疑問に思うかもしれません。それは[おまけ](#おまけ)にて触れています。
:::

ヘッダーには以下の3つが表示されます。
* LIFFアプリ名
* LIFFアプリのエンドポイントURL
* 閉じるアイコン

シェアアイコンが表示されなくなりました。

また、先ほどはなかったフッターがあります。
* 戻るアイコン
* 進むアイコン
* 更新アイコン
* シェアアイコン
* 三点リーダーアイコン
が表示されています。

シェアアイコンはフッターに移動していますね。
<img width='80%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/94d366dd-c660-a186-340b-ec9d06425e54.png'>

また、シェアアイコンの機能に大きな違いがあります。
LIFFブラウザではKeepメモへの共有がありましたが、こちらはありません。
<img width='80%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/c55a9845-dbde-26f7-be3a-f6fbb4fa8fc7.png'>

Keepメモへの共有は三点リーダーアイコンに移動しています。
<img width='80%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/7b388c8b-c6b5-9e8a-4912-d14491be7672.png'>

また、LINE内ブラウザで開いた場合、Developerコンソール上で指定したLIFFアプリのサイズはまったく影響しません。
どのサイズを選択していても、画面いっぱいにページが表示されます。

あくまでもLIFFブラウザで開いたときのサイズ指定になるので、LINE内ブラウザには関係がありません。

このように、見た目とブラウザ内の機能でも大きな違いがありました。

## まとめ
用語の部分だけでなく、機能と見た目の違いについても解説しました。

LIFFブラウザとLINE内ブラウザ、どちらもLINE上で立ち上がるブラウザなので、同じようなものに思えますが、完全に別物であることがわかりました。

この違いをしっかり抑えて、開発に活かしていきたいです。

## おまけ
### ぶちあたった問題
私がハマっていた泥沼というのが
LINEからLIFFアプリにアクセスしているのに、なぜかログインができない
という問題でした。

`liff.init()`をしていればLIFFアプリでは自動でログインがされるはずなのに、`liff.isLoggedIn()`を確認しても`false`となっているという謎の状況にかなりの時間を費やしました。

* 外部ブラウザ、LINE内ブラウザでは`liff.login()`でログインが必要
* LIFFブラウザでは`liff.init()`時に自動でログインされる

という記事内でも紹介した公式サイトの記載を見つけましたが、何が違うのかがまったくわかりませんでした。

LINE側での設定の問題なのか、`liff.init()`の実装の問題なのか、など散々試した挙げ句、衝撃的な事実に気づきます。

### しょうもないミス
以下に示した２つのリンク、上はLIFFブラウザで立ち上がりますが、下はLINE内ブラウザで立ち上がります。

一見まったく同じデモアプリを参照しているように思えます。
違いがわかるでしょうか。

<img width='80%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/6004ed6f-f528-bd08-91dd-fcd82a9fde69.png'>

実は、下の部分はURLが若干誤っています。
`liff.line.me./`と`me`のあとに余計なドットが含まれている事がわかります。
検証をする際、URLを手打ちで入力していたので、打ち間違いをしていたのでした。

### LIFFブラウザとLINE内ブラウザの分岐
ここからは推測ですが、おそらく
`https://liff.line.me/`
というURLが含まれる場合に、LIFFブラウザで立ち上げているのだと思われます。
そして、それ以外はすべてLINE内ブラウザで立ち上げる、というような処理になっているのでしょう。

私はURLのタイプミスをしていたため、LIFFアプリを開いているのにもかかわらず、LINE内ブラウザで立ち上がっており`liff.init()`時に自動ログインが実行されない、と言う事態に陥っていたのでした。

蓋を開けてみれば何のことはない、ただのタイプミスなのですが、それをただのタイプミスで終わらせず、ちゃんと調べてまとめることができたので、良しとしたいですね。

※余計なドットが含まれていても、なぜ目的のサイトにアクセスできたのか、ということについての疑問が実は残っているのですが、これはいつかの宿題にしたいと思います。