URL アドレス指定可能な Lightning Web コンポーネント (LWC)



https://www.trailtwo.com/blog/2022-10-11/url-addressable-lightning-web-components-lwc

Salesforce Lightning Web コンポーネント (LWC) の多くの厄介な制限の 1 つは、構成可能な URL を介してコンポーネントを直接アドレス指定できないことです。


この問題に直面した方は、LWC を Aura コンポーネントでラップしたり、Lightning アプリケーションページを作成したりといった一般的な回避策を試したことがあるかもしれません。確かにこの方法は有効ですが、Lightning Web コンポーネントごとにラッパーを作成するよりも、もっと良い方法があるようです。


はい、できますよ！


シンプルで再利用可能な Aura コンポーネントを使用することで、すべての Lightning Web コンポーネントをラップし、再利用性のまったく新しい世界を切り開くことができます。


----

Lightning Web Components (LWC) は URL でアクセスできないと説明しましたが、これは厳密には正しくありません。LWC にアクセスするには、URL に追加するためにエンコードされたページ参照が必要です。

<Salesforce ドメイン>/one/one.app#<エンコードされたページ参照>

例: <Salesforce ドメイン>/one/one.app#eyJjb21wb25lbnREZWYiOiJUMkRvY3M6ZG9jdW1lbnRNZXJnZSIsImF0dKJpYnV0ZXMiOnsiY19fbHdjKjoiVDJEb2NzOmRvY3VtZW50TWVyZ2UiLCJjX19pZCI6IjAwNjUyMDAwMDBFTDE2T0FBVCIsImNfX2RvY3VtZW50RGV2ZWxvcGVyTmFtZSI6IkNPUl9EZXNpZ25fQWdyZWVtZW50X1KlbXBsYXRlIn0sInN0YXRlIjp7fX0%3D

人間が読める形式ではありません (URL フィールドで構築できるものでもありません) が、これが Addressable LWC Wrapper を有効にするための鍵となります。


# まず、Aura コンポーネントを作成します。これは、すべての Lightning Web コンポーネントをラップできる単一の Aura コンポーネントになります。


+ force-app/main/default/aura/AddressableLWC.cmp
```
<aura:component implements="lightning:isUrlAddressable" description="c:AddressableLWC component">
	<aura:handler name="init" value="{!this}" action="{!c.init}"></aura:handler>
	<aura:handler name="change" value="{!v.pageReference}" action="{!c.init}"></aura:handler>
	<lightning:navigation aura:id="navService"></lightning:navigation>
</aura:component>
```

lightning:isUrlAddressable を実装し（当然ですね！）、Aura コンポーネントが正しく動作するように「init」ハンドラと「change」ハンドラを定義する必要があります。また、LWC にリダイレクトするために Lightning Navigation Service を組み込む必要があります。


# このコンポーネントへのURLを作成し、パラメータを渡すことができます。パラメータの1つはLightning Webコンポーネントの名前になります。

<あなたの Salesforce ドメイン>/lightning/cmp/ c__AddressableLWC?c__lwc=<lwc 名> &<パラメーター>=<値>…

+ force-app/main/default/aura/AddressableLWC.js

```Javascript
({
    init : function(component, event, helper) {
		let pageRef = component.get("v.pageReference");

		let encodedCompDef = btoa(
			JSON.stringify({
				componentDef: pageRef.state.c__lwc,
				attributes: pageRef.state
			})
		);

		component.find("navService").navigate(
			{
				type: "standard__webPage",
				attributes: {
					url: "/one/one.app#" + encodedCompDef
				}
			},
			true
		);
    }
})
```

# AddressableLWC JavaScript コントローラーの説明

まず PageReference を取得して、AddressableLWC Aura コンポーネントに渡されるパラメータにアクセスできるようにします。

次に、componentDef を Lightning Web コンポーネント名に設定して JSON ページ参照を作成し、ページ参照状態の残りのパラメータを、attributes プロパティの Aura コンポーネントに渡します。

次に、JavaScript 関数 bota() を使用してページ参照をバイナリ文字列から ASCII 文字列にエンコードします。

```Javascript
let pageRef = component.get("v.pageReference");

let encodedCompDef = btoa(
  JSON.stringify({
    componentDef: pageRef.state.c__lwc,
    attributes: pageRef.state
  })
);
```

最後に、ナビゲーションサービスを使用して、Lightning Webコンポーネント用に構築されたURLを使用してLWCに移動します。


```Javascript
component.find("navService").navigate(
  {
    type: "standard__webPage",
    attributes: {
      url: "/one/one.app#" + encodedCompDef
    }
  },
  true
);
```


注: ナビゲーションサービスの2番目のパラメータ「replace」はtrueに設定されています。これにより、Auraコンポーネントへの最初のナビゲーションウィンドウがLightning Webコンポーネントへのナビゲーションに置き換えられます。


# まとめ

AddressableLWC Aura コンポーネントをテストするために、シンプルな Lightning Web コンポーネントを作成しましょう。

+ Force-app/main/default/lwc/helloWorld.html

```Javascript
<template>
    <lightning-card title="Addressable LWC Hello World Example">
      {c__data}
    </lightning-card>
</template>
```

+ Force-app/main/default/lwc/helloWorld.js

```Javascript
import { LightningElement, api } from 'lwc';

export default class HelloWorld extends LightningElement {
    @api
	c__data;
}
```

+ force-app/main/default/lwc/helloWorld.js-meta.xml

```Javascript
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>50.0</apiVersion>
    <isExposed>true</isExposed>
</LightningComponentBundle>
```

これで、次の URL を使用して helloWorld Lightning Web コンポーネントをアドレス指定できるようになりました。

<あなたの Salesforce ドメイン>/lightning/cmp/c__AddressableLWC?c__lwc=c:helloWorld&c__data=Hello World!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/0ce18c7c-6d33-4707-b0ec-4d8653b39c29.png)