LIFFをNext.jsなどで使いやすくするHookライブラリ’use-line-liff’をリリースしました
npm: https://www.npmjs.com/package/use-line-liffGitHub: https://github.com/hideokamoto/use-line-liff 背景 Next.j […]
目次
npm: https://www.npmjs.com/package/use-line-liff
GitHub: https://github.com/hideokamoto/use-line-liff
背景
Next.jsでLIFF SDKを利用する場合、SSRでの実行を避ける処理が必要です。これは、LIFF SDKがおそらく内部でwindow
変数を利用しているため、window is not defined
エラーが発生することが原因です。
そのため、LINE公式のサンプルなどでは、useEffect
とpageProps
を利用する方法が紹介されています。
/**
* @see https://github.com/line/line-liff-v2-starter/blob/master/src/nextjs/pages/_app.js
**/
function MyApp({ Component, pageProps }) {
const [liffObject, setLiffObject] = useState(null);
const [liffError, setLiffError] = useState(null);
// Execute liff.init() when the app is initialized
useEffect(() => {
// to avoid `window is not defined` error
import("@line/liff").then((liff) => {
console.log("start liff.init()...");
liff
.init({ liffId: process.env.LIFF_ID })
.then(() => {
console.log("liff.init() done");
setLiffObject(liff);
})
.catch((error) => {
console.log(`liff.init() failed: ${error}`);
if (!process.env.liffId) {
console.info(
"LIFF Starter: Please make sure that you provided `LIFF_ID` as an environmental variable."
);
}
setLiffError(error.toString());
});
});
}, []);
// Provide `liff` object and `liffError` object
// to page component as property
pageProps.liff = liffObject;
pageProps.liffError = liffError;
return <Component {...pageProps} />;
}
ただ、個人的にはStripe SDKのように「useXXX
でクライアントのインスタンスを取得して、undefined
やnull
でなければロード完了している」パターンの方が使いやすいので、React Hookにしてみました。
use-line-liffの使い方
一般的なReact Hookライブラリ(Provider付き)なので、インストールして使うだけです。
% npm install use-line-liff
Next.jsの場合、pages/_app.js
またはpages/_app.tsx
にProviderを追加します。
import { LiffProvider } from 'use-line-liff';
function MyApp({ children }) {
return (
<LiffProvider liffId={process.env.NEXT_PUBLIC_LIFF_ID}>
{children}
</LiffProvider>
);
};
export default MyApp;
あとはuseLiff
フックを使ってLIFF SDKクライアントを取得するだけです。
import { useEffect } from 'react';
import { useLiff } from 'use-line-liff';
const Home = () => {
const { liff } = useLiff();
useEffect(() => {
if (!liff) return;
if (!liff.isLoggedIn()) {
liff.login();
}
liff.getProfile();
...
Mockを使う
LIFF Mockがローカル開発で便利そうでしたので、バンドルしてみました。
Providerでオンオフの設定ができます。
import { LiffProvider } from 'use-line-liff';
function MyApp({ children }) {
return (
<LiffProvider
liffId={process.env.NEXT_PUBLIC_LIFF_ID}
mock={{
enable: true,
}}
>
{children}
</LiffProvider>
);
};
export default MyApp;
ロード後にモックの中身を書き換えることも可能です。
function MyApp({ Component, pageProps }: AppProps) {
return (
<LiffProvider
liffId={process.env.NEXT_PUBLIC_LIFF_ID as string}
mock={{
enable: true,
mockDidLoaded: (p) => {
return {
...p,
getProfile: {
...p.getProfile,
userId: 'custom-user-id'
}
}
}
}}
>
<Component {...pageProps} />
</LiffProvider>
)
}
実運用では、process.env
あたりで「ローカルの時だけモックを有効にする」ような使い方ができるかなと思います。
mock
がenable: false
の場合、mockDidLoaded
は動きませんので、こちらまで分岐を書く必要はない(はず)です。
今後について
LINE(LIFF)は触り始めたばかりなので、これの開発の前に「これを使ったLIFFアプリ」をリリースしたいなと思っています。その中で欲しくなった機能があれば、少しずつ追加していく予定です。
「Inspectorの方もサポートすると便利そうだなー」とか、「中の人的には、Stripeのプラグインも入れたいなぁ」とか、妄想は広がるばかりですが。。。
あとは・・・Gatsbyプラグインとかかなぁ・・・