<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Luke Secomb</title>
    <description>The latest articles on Forem by Luke Secomb (@lukethacoder).</description>
    <link>https://forem.com/lukethacoder</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F164500%2Faecd8212-9e6d-44d2-86cc-6ab0b1edd2e8.jpg</url>
      <title>Forem: Luke Secomb</title>
      <link>https://forem.com/lukethacoder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/lukethacoder"/>
    <language>en</language>
    <item>
      <title>Local LWC Development with real @AuraEnabled method calls</title>
      <dc:creator>Luke Secomb</dc:creator>
      <pubDate>Wed, 05 Feb 2025 00:06:12 +0000</pubDate>
      <link>https://forem.com/lukethacoder/local-lwc-development-with-real-auraenabled-method-calls-4mfb</link>
      <guid>https://forem.com/lukethacoder/local-lwc-development-with-real-auraenabled-method-calls-4mfb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This article explains how to call real &lt;code&gt;@AuraEnabled&lt;/code&gt; Apex methods from your local development server. We will use &lt;a href="https://lwc.garden/?utm_campaign=blog-lukesecomb-digital" rel="noopener noreferrer"&gt;LWC Garden&lt;/a&gt; as our server of choice. However, this approach can also work within a vanilla LWR setup if required.&lt;/p&gt;

&lt;p&gt;Let's begin with an example Apex class to get us started:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apex"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="kd"&gt;sharing&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AccountController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="cm"&gt;/**
   * @description Method to fetch Accounts by a list of Ids
   * @param accountIds Account Ids to query for
   * @return List of matching Accounts
   */&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getAccountsById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;accountIds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;accountIds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;
      &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Account&lt;/span&gt; 
      &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;accountIds&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="cm"&gt;/**
   * @description Method to fetch Accounts by a list of Names
   * @param accountNames Account Names to query for
   * @return List of matching Accounts
   */&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getAccountsByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;accountNames&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;accountIds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;
      &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Account&lt;/span&gt; 
      &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;accountNames&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Folder Structure
&lt;/h2&gt;

&lt;p&gt;Here’s a quick look at the folder structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── __mocks__/
│   └── @salesforce/
│       └── apex/
│           ├── AccountController.js (or the following two files)
│           ├── AccountController.getAccountsById.js
│           └── AccountController.getAccountsByName.js
├── force-app/
│   └── main/
│       └── default/
│           ├── apex/
│           │   └── AccountController.cls
│           └── lwc/
│               └── accountManager/
│                   ├── accountManager.css
│                   ├── accountManager.html
│                   ├── accountManager.js
│                   └── accountManager.js-meta.xml
├── package.json
├── lwr.config.json (or lwc.config.json)
└── sfdx-project.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Depending on approach, you may only require a single mock file for the Apex class (e.g. &lt;code&gt;AccountController.js&lt;/code&gt;) instead of one file per method. Checkout the &lt;a href="https://lwc.garden/packages/apex?utm_campaign=blog-lukesecomb-digital" rel="noopener noreferrer"&gt;&lt;code&gt;@lwc-garden/utils&lt;/code&gt;&lt;/a&gt; documentation if you're unsure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;Before diving into calling real &lt;code&gt;@AuraEnabled&lt;/code&gt; methods, let's review a simpler form of method mocking. Depending on your use case, this might be enough to get you running locally.&lt;/p&gt;

&lt;p&gt;We'll focus on the vanilla approach for now, which requires creating a new JavaScript file for each Apex Method. If you'd prefer a single file per Apex class, checkout the &lt;a href="https://lwc.garden/packages/apex?utm_campaign=blog-lukesecomb-digital" rel="noopener noreferrer"&gt;&lt;code&gt;@lwc-garden/utils&lt;/code&gt;&lt;/a&gt; documentation.&lt;/p&gt;

&lt;p&gt;lwr.config.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"modules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@salesforce/apex/AccountController.getAccountsById"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./__mocks__/@salesforce/apex/AccountController.getAccountsById.js"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@salesforce/apex/AccountController.getAccountsByName"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./__mocks__/@salesforce/apex/AccountController.getAccountsByName.js"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration maps standard on-platform imports to your local mock JavaScript files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing the Apex Mocks
&lt;/h2&gt;

&lt;p&gt;Now we'll configure our mocks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./__mocks__/@salesforce/apex/AccountController.getAccountsById.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getAccountsById&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;001dL00000jNfdgQAC&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Google Inc.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;001dL00000jOfdhQAC&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Google Inc.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./__mocks__/@salesforce/apex/AccountController.getAccountsByName.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getAccountsByName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;001dL00000jNfdgQAC&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Google&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;001dL00000jOfdhQAC&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Microsoft&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may choose to add some smarts to your mocks if you wish. Here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ./__mocks__/@salesforce/apex/AccountController.getAccountsById.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ACCOUNTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;001dL00000jNfdgQAC&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Google&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;001dL00000jOfdhQAC&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Microsoft&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getAccountsById&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;accountIds&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;ACCOUNTS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;accountIds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Calling real &lt;code&gt;@AuraEnabled&lt;/code&gt; Apex Methods
&lt;/h2&gt;

&lt;p&gt;To call real Apex methods, we need a local server to bypass browser-based CORS errors. We'll use &lt;a href="https://hono.dev/" rel="noopener noreferrer"&gt;Hono&lt;/a&gt;, though other frameworks (e.g., Express, Koa, Fastify) can also work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hono Configuration
&lt;/h3&gt;

&lt;p&gt;To get started install the following packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm add hono @hono/node-server
pnpm add &lt;span class="nt"&gt;-D&lt;/span&gt; @types/node tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once installed, add a new entry to your &lt;code&gt;package.json&lt;/code&gt; &lt;code&gt;"scripts"&lt;/code&gt; object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"run-server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsx watch server.ts"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;server.ts&lt;/code&gt; file to hold our Hono configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Hono&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hono&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hono/cors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;serve&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@hono/node-server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Hono&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/proxy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/proxy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;q&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;duplex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;half&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;newResponse&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3003&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server is running on http://localhost:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run the Hono server, run the &lt;code&gt;pnpm run-server&lt;/code&gt; command we added above.&lt;/p&gt;

&lt;p&gt;To test this is running correctly, open your browser and go to &lt;a href="http://localhost:3003/proxy?q=https://example.com" rel="noopener noreferrer"&gt;http://localhost:3003/proxy?q=https://example.com&lt;/a&gt;. If you are greeted with some HTML, it means the server is running correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Editing the Apex Mocks
&lt;/h3&gt;

&lt;p&gt;For these mocks, we'll use the &lt;a href="https://lwc.garden/packages/utils?utm_campaign=blog-lukesecomb-digital" rel="noopener noreferrer"&gt;&lt;code&gt;@lwc-garden/utils&lt;/code&gt;&lt;/a&gt; package to allow us to define all our methods within a single JavaScript file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm add @lwc-garden/utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once installed, we will need to edit our &lt;code&gt;lwr.config.json&lt;/code&gt; file to tell LWC Garden where to find our apex methods.&lt;/p&gt;

&lt;p&gt;lwr.config.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"@lwc-garden/utils/resolvers/apex.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"paths"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"__mocks__/@salesforce/apex/"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;For more information on &lt;code&gt;@lwc-garden/utils&lt;/code&gt; configuration, including extra configuration for Static Resources and Custom Labels, checkout the &lt;a href="https://lwc.garden?utm_campaign=blog-lukesecomb-digital" rel="noopener noreferrer"&gt;LWC Garden&lt;/a&gt; documentation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that we have our mapping configured, lets create our JavaScript file to call our &lt;code&gt;@AuraEnabled&lt;/code&gt; apex.&lt;/p&gt;

&lt;p&gt;Before we jump in, we'll need to find two things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;SALESFORCE_URL&lt;/code&gt;: This is your Experience Cloud BASE URL. e.g. &lt;code&gt;https://company--dev.sandbox.my.site.com/mycommunity&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CLASS_NAME_ID&lt;/code&gt;: This is a unique Id that is assigned to each Apex Class. This can be found by inspecting the request payload when calling the method on-platform.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// __mocks__/@salesforce/apex/AccountController.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PROXY_BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:3003&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;WEBRUNTIME_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/webruntime/api/apex/execute&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// TODO: REPLACE THIS&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SALESFORCE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://company--dev.sandbox.my.site.com/mycommunity`&lt;/span&gt;

&lt;span class="c1"&gt;// TODO: REPLACE THIS&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CLASS_NAME_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@udd/01p8r000008CmFZ&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PROXY_BASE_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/proxy?q=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;SALESFORCE_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;WEBRUNTIME_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchHelper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;methodName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isWire&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myHeaders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;myHeaders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;myHeaders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cookie&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CookieConsentPolicy=0:1; LSKey-c$CookieConsentPolicy=0:1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;classname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CLASS_NAME_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;methodName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;isContinuation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;cacheable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BASE_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;?language=en-US&amp;amp;asGuest=true&amp;amp;htmlEncode=false`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;myHeaders&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;follow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cacheable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;returnValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;returnValue&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getAccountsById&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nf"&gt;fetchHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;getAccountsById&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getAccountsByName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nf"&gt;fetchHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;getAccountsByName&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;And thats it, boot up your local dev server using &lt;code&gt;npx @lwc-garden/core dev&lt;/code&gt; and your apex methods will now be calling your actual Salesforce Org.&lt;/p&gt;

</description>
      <category>salesforce</category>
      <category>lwc</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Lightning Web Components: Custom Nested Components</title>
      <dc:creator>Luke Secomb</dc:creator>
      <pubDate>Mon, 20 Mar 2023 02:15:28 +0000</pubDate>
      <link>https://forem.com/lukethacoder/lightning-web-components-custom-nested-components-171n</link>
      <guid>https://forem.com/lukethacoder/lightning-web-components-custom-nested-components-171n</guid>
      <description>&lt;p&gt;Lightning Web Runtime, or LWR for short was released back in &lt;a href="https://help.salesforce.com/s/articleView?id=release-notes.rn_experiences_developers_lwr.htm&amp;amp;release=230&amp;amp;type=5" rel="noopener noreferrer"&gt;Spring 21 (v51.0)&lt;/a&gt;. Even before the release of LWR, most developers dreamed of being able to build custom nested components. We could see that OOTB (Out Of The Box) components could use them (see Tabs component).&lt;/p&gt;

&lt;p&gt;Salesforce recently released the ability to build custom LWCs with child &lt;code&gt;&amp;lt;slot/&amp;gt;&lt;/code&gt;'s, to allow nesting of components. Nested LWCs allow you to compose multiple components together into a single component. The child components maintain their own life cycle and can communicate with each other through events, making it easy to create flexible and dynamic apps.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before continuing, Aura based Communities are (sadly) not supported. So if you're currently using them it might be time to make the switch to LWR.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Code Example
&lt;/h2&gt;

&lt;p&gt;Enough talk, lets jump into the code and see the magic happen.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTML
&lt;/h3&gt;

&lt;p&gt;We'll start by creating the HTML template to hold our &lt;code&gt;&amp;lt;slot/&amp;gt;&lt;/code&gt;'s.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;if:false=&lt;/span&gt;&lt;span class="s"&gt;{isAura}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"region1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/slot&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"region2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/slot&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"region3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/slot&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  JavaScript
&lt;/h3&gt;

&lt;p&gt;Now lets have a look at the JavaScript. The important part (or magic) here is the &lt;code&gt;@slot&lt;/code&gt; definitions in the comment directly above the LWC export. Without these definitions, the dynamic components will not work.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;isAura&lt;/code&gt; check also ensures this component shows a warning in the experience builder when it is being used from within an Aura based community.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LightningElement&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lwc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @slot region1
 * @slot region2
 * @slot region3
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NestedLWCs&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;LightningElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;isAura&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Metadata XML
&lt;/h3&gt;

&lt;p&gt;Make sure your &lt;code&gt;.xml&lt;/code&gt; file is setup to be available in the experience builder. The key values are setting &lt;code&gt;isExposed&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; and including both &lt;code&gt;lightningCommunity__Page&lt;/code&gt; and &lt;code&gt;lightningCommunity__Default&lt;/code&gt; as &lt;code&gt;targets&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;LightningComponentBundle&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://soap.sforce.com/2006/04/metadata"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;apiVersion&amp;gt;&lt;/span&gt;57.0&lt;span class="nt"&gt;&amp;lt;/apiVersion&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;isExposed&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/isExposed&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;masterLabel&amp;gt;&lt;/span&gt;Nested LWCs&lt;span class="nt"&gt;&amp;lt;/masterLabel&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;Nested LWC magic&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;targets&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;target&amp;gt;&lt;/span&gt;lightningCommunity__Page&lt;span class="nt"&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;target&amp;gt;&lt;/span&gt;lightningCommunity__Default&lt;span class="nt"&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/targets&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/LightningComponentBundle&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Experience Builder
&lt;/h2&gt;

&lt;p&gt;Now lets open up the Experience Builder and see our custom LWC in action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3y6ifuk46ocgyd3tzcai.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3y6ifuk46ocgyd3tzcai.gif" alt="Experience Builder: Draging our custom LWC onto the page" width="2038" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can also nest components within other nested components. I am not aware of any limitation here. I was able to place up to 10 levels deep without any issues, noting theses are very barebones test LWCs. More complex LWCs may start affecting performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpnlmvk5u33k2h2ku035u.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpnlmvk5u33k2h2ku035u.gif" alt="Experience Builder: Draging our custom LWC onto the page" width="2037" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;In summary, nested LWCs provide a powerful and flexible way for developers to create custom components that can be composed of multiple other components, making it easier to build dynamic and reusable apps on the Experience Cloud platform.&lt;/p&gt;

</description>
      <category>salesforce</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Building Custom Mixins in Lightning Web Components (LWC)</title>
      <dc:creator>Luke Secomb</dc:creator>
      <pubDate>Thu, 09 Mar 2023 22:44:37 +0000</pubDate>
      <link>https://forem.com/lukethacoder/lwc-custom-mixins-1ac2</link>
      <guid>https://forem.com/lukethacoder/lwc-custom-mixins-1ac2</guid>
      <description>&lt;p&gt;Mixins (or Abstract subclasses) are templates for classes that allow us to write generic functionality to be reused. Given the nature of classes, it is not possible to have more than one superclass. Mixins allow us to pass the base class as a property and unlock nested inheritance.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript Mixin Usage
&lt;/h2&gt;

&lt;p&gt;Before we dive into an LWC example, lets look at how we can use mixins in a plain javascript environment.&lt;/p&gt;

&lt;p&gt;Firstly, we must create a mixin function that our classes can use. This should be a piece of generic functionality that multiple classes can utalise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// A simple Mixin method&lt;/span&gt;
&lt;span class="c1"&gt;// adds the `windowSize()` method to classes that implement this mixin&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;WindowSizeMixin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BaseClass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;BaseClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;windowSize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerWidth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WindowSizeMixin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./windowSizeMixin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Implementing the `WindowSizeMixin` gives us access to the&lt;/span&gt;
&lt;span class="c1"&gt;// `this.windowSize` getter&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;WindowSizeMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BaseClass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;getWindowSize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;windowSize&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, calling the &lt;code&gt;getWindowSize()&lt;/code&gt; function on our Header class will return the object defined in the &lt;code&gt;WindowSizeMixin&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  LWC Mixin Usage
&lt;/h2&gt;

&lt;p&gt;Now we have a basic understanding of how mixins work in JavaScript, lets look at how the concept applies to LWC. Using mixins in LWC is almost identical with one difference, your &lt;code&gt;BaseClass&lt;/code&gt; should be &lt;code&gt;LightningElement&lt;/code&gt; (or another class that has extended &lt;code&gt;LightningElement&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;We'll assume the same above mixin source code that we used above (&lt;code&gt;WindowSizeMixin&lt;/code&gt;) but instead our implementation will be a LWC component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// don't forget to import LightningElement, we need to extend it as our base class&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LightningElement&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lwc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// assume our mixin has been created as a separate LWC to be used by multiple components&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WindowSizeMixin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c/windowSizeMixin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// LWC expects a default export of our `LightingElement` extended component&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;WindowSizeMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LightningElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;getWindowSize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// available via the WindowSizeMixin&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;windowSize&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Stacking Mixins
&lt;/h2&gt;

&lt;p&gt;The beauty of mixins is that you can use more than one. This can be useful for creating smaller snippet mixins for similar functionality that is used across multiple LWCs.&lt;/p&gt;

&lt;p&gt;Lets have a quick look at an example. We will create another mixin method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DateMixin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BaseClass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;BaseClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// a function that returns the current date as an object&lt;/span&gt;
    &lt;span class="nf"&gt;getDate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getDate&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMonth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets update our LWC example from above to include the new &lt;code&gt;DateMixin&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// don't forget to import LightningElement, we need to extend it as our base class&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LightningElement&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lwc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// assume our mixins have been created as a separate LWC to be used by multiple components&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WindowSizeMixin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c/windowSizeMixin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DateMixin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c/dateMixin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// LWC expects a default export of our component&lt;/span&gt;
&lt;span class="c1"&gt;// we can stack mixins here&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;DateMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nc"&gt;WindowSizeMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LightningElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;getWindowSize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// available via the WindowSizeMixin&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;windowSize&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;getCurrentDate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// available via the DateMixin&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getDate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using &lt;code&gt;@wire&lt;/code&gt; in a Custom Mixin
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.data_wire_service_about" rel="noopener noreferrer"&gt;&lt;code&gt;@wire&lt;/code&gt;&lt;/a&gt; is a service that streams immutable data to the component. This is heavily used in on platform development and a must when it comes to building dynamic components.&lt;/p&gt;

&lt;p&gt;Lets have a look at a simple example mixin that uses the standard &lt;a href="https://developer.salesforce.com/docs/component-library/documentation/en/lwc/reference_wire_adapters_record" rel="noopener noreferrer"&gt;&lt;code&gt;getRecord&lt;/code&gt;&lt;/a&gt; wire method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;wire&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lwc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getRecord&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lightning/uiRecordApi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AccountWireMixin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BaseClass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;BaseClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// explicitly not setting recordId so that the consuming&lt;/span&gt;
    &lt;span class="c1"&gt;// component can choose how it wishes to implement it (e.g @api, get/set)&lt;/span&gt;
    &lt;span class="c1"&gt;// recordId&lt;/span&gt;

    &lt;span class="c1"&gt;// this can be dynamically changed by the implementing class if needed&lt;/span&gt;
    &lt;span class="c1"&gt;// this array acts as a default field list&lt;/span&gt;
    &lt;span class="nx"&gt;fieldRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Account.Id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Account.Name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Account.Phone&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;wire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getRecord&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;recordId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$recordId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$fieldRef&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nf"&gt;wiredGetRecord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// you can choose to either set the data to a variable for you component to consume&lt;/span&gt;
      &lt;span class="c1"&gt;// or fire off a function that your consuming component can override.&lt;/span&gt;
      &lt;span class="c1"&gt;// for this example, we will call a method&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handleWiredAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * This method should be overriden by the consuming component
     */&lt;/span&gt;
    &lt;span class="nx"&gt;handleWiredAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// TODO: handle errors&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// TODO: handle success&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can update our above example and stack the &lt;code&gt;AccountWireMixin&lt;/code&gt; on top.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// don't forget to import LightningElement, we need to extend it as our base class&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LightningElement&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lwc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// assume our mixins have been created as a separate LWC to be used by multiple components&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WindowSizeMixin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c/windowSizeMixin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DateMixin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c/dateMixin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AccountWireMixin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c/accountWireMixin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// LWC expects a default export of our component&lt;/span&gt;
&lt;span class="c1"&gt;// we can stack mixins here&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AccountWireMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nc"&gt;DateMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;WindowSizeMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LightningElement&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ... existing code&lt;/span&gt;

  &lt;span class="c1"&gt;// override the shell method defined in the AccountWireMixin&lt;/span&gt;
  &lt;span class="nx"&gt;handleWiredAccount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// TODO: handle errors&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Oh no, something went wrong &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// TODO: handle success&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;We have account data, yay &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;In conclusion, mixins are an incredibly useful tool in LWC development. They allow us to write generic, reusable functionality that can be shared between multiple components. By stacking multiple mixins, we are able to compose complex components from smaller, focused mixins. Mixins help keep our code DRY (Don't Repeat Yourself) and maintainable.&lt;/p&gt;

</description>
      <category>salesforce</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Salesforce Trekken: Salesforce CMS Migration Tool built with Tauri, React, TailwindCSS &amp; Vite</title>
      <dc:creator>Luke Secomb</dc:creator>
      <pubDate>Fri, 13 Jan 2023 15:56:50 +0000</pubDate>
      <link>https://forem.com/lukethacoder/salesforce-trekken-salesforce-cms-migration-tool-built-with-tauri-react-tailwindcss-vite-l67</link>
      <guid>https://forem.com/lukethacoder/salesforce-trekken-salesforce-cms-migration-tool-built-with-tauri-react-tailwindcss-vite-l67</guid>
      <description>&lt;p&gt;The Salesforce CMS data migration experience is lacking. There is no bulk export, and there is no sorting/filtering of content and you are sent an email link instead of being able to directly download the zip file.&lt;/p&gt;

&lt;p&gt;Salesforce Trekken aims to rethink the Salesforce CMS migration experience. Using modern web technologies and thoughtful a user experience, migrating Salesforce CMS data has never been easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;Salesforce Trekken allows users to authenticate using one of two methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_install_cli.htm" rel="noopener noreferrer"&gt;sfdx cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Access Token (and Instance URL)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_rest.htm" rel="noopener noreferrer"&gt;Salesforce REST API&lt;/a&gt; is used to fetch CMS Channels and the CMS Content after a specific channel has been selected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Multiple Authentication Methods (&lt;code&gt;sfdx cli&lt;/code&gt; or ACCESS_TOKEN)&lt;/li&gt;
&lt;li&gt;Channel Selection: Choose the right CMS Channel to export data from&lt;/li&gt;
&lt;li&gt;Feature Rich Export Table&lt;/li&gt;
&lt;li&gt;Bundled Zip file export, ready to be imported into your target org.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Walkthrough
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Select Your Authentication Method
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2swk92fgkr7pnxit5edq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2swk92fgkr7pnxit5edq.png" alt="Salesforce Trekken: Select Authetnication Method Screenshot" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Select An Org
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4uqkgivqg3ypozqya2i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4uqkgivqg3ypozqya2i.png" alt="Salesforce Trekken: Select An Org Screenshot" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Select A CMS Channel
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx3pg9py9p0sdvx2vre10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx3pg9py9p0sdvx2vre10.png" alt="Salesforce Trekken: Select A CMS Channel Screenshot" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Search/Filter/Sort and Select Content
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgj1ibx39prmfo09zr6l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgj1ibx39prmfo09zr6l.png" alt="Salesforce Trekken: Select CMS Content Screenshot" width="800" height="621"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Select An Output Folder
&lt;/h4&gt;

&lt;p&gt;and whether to include images as part of the export.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbl997pnp7qjrl8cgoemg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbl997pnp7qjrl8cgoemg.png" alt="Salesforce Trekken: Select An Output Folder Screenshot" width="800" height="617"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Success
&lt;/h4&gt;

&lt;p&gt;Either open the source folder or start over.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u7mwkz4ua81c6zn9gdg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u7mwkz4ua81c6zn9gdg.png" alt="Salesforce Trekken: Successful Export Screenshot" width="800" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your content is now ready to import into your target org.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are working with &lt;code&gt;cms_image&lt;/code&gt;, make sure you import your images zip file first&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;Now you've seen the powers of Salesforce Trekken and its improved user experience compared to the standard salesforce experience.&lt;/p&gt;

&lt;p&gt;Want to find out more and/or download, checkout the &lt;a href="https://trekken.lukesecomb.digital/" rel="noopener noreferrer"&gt;Salesforce Trekken site&lt;/a&gt;&lt;/p&gt;

</description>
      <category>salesforce</category>
      <category>tooling</category>
      <category>showdev</category>
      <category>tauri</category>
    </item>
    <item>
      <title>Spotify Playlist Backup using Github Actions</title>
      <dc:creator>Luke Secomb</dc:creator>
      <pubDate>Thu, 01 Dec 2022 13:55:04 +0000</pubDate>
      <link>https://forem.com/lukethacoder/spotify-playlist-backup-using-github-actions-3h8h</link>
      <guid>https://forem.com/lukethacoder/spotify-playlist-backup-using-github-actions-3h8h</guid>
      <description>&lt;p&gt;Platforms come and go, and Spotify most likely wont be around forever. What would you do if you woke up tomorrow and Spotify was gone. I know I wouldn't be too happy, after spending countless hours carefully curating well over 200 playlists.&lt;/p&gt;

&lt;p&gt;So, to save your playlists from being erased from the internet forever, lets create a small python script to back them up. This post outlines the steps to configue and a basic walkthrough of my &lt;a href="https://github.com/lukethacoder/spotify-playlist-backup" rel="noopener noreferrer"&gt;spotify-playlist-backup&lt;/a&gt; project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spotify Developer Application
&lt;/h2&gt;

&lt;p&gt;Before we can jump into the code we need to setup our own &lt;a href="https://developer.spotify.com/dashboard/applications" rel="noopener noreferrer"&gt;Spotify Developer Application&lt;/a&gt;. This will require you to have a Spotify account (a free account should work). Once logged in, create a new application and save the &lt;code&gt;CLIENT_ID&lt;/code&gt; and &lt;code&gt;CLIENT_SECRET&lt;/code&gt; for later. Make sure you set &lt;code&gt;http://localhost:3000/callback&lt;/code&gt; as a return url for your application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8w5uirpfxktfkhlxtbrn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8w5uirpfxktfkhlxtbrn.jpg" alt="spotify dashboard application page" width="800" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Into the code
&lt;/h2&gt;

&lt;p&gt;Clone the &lt;a href="https://github.com/lukethacoder/spotify-playlist-backup" rel="noopener noreferrer"&gt;spotify-playlist-backup&lt;/a&gt; repo and create a new &lt;code&gt;.env&lt;/code&gt; file. Copy and paste in the following code snippet and replace the values with your configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .env file
# Values from your Spotify Developer Application
SPOTIFY_CLIENT_ID=laboriselitutenimdoculpa
SPOTIFY_CLIENT_SECRET=laboriselitutenimdoculpa

# Your Spotify Username
SPOTIFY_USERNAME=12345678910

# Your Spotify Password
SPOTIFY_PASSWORD=abcdefghijklmnopqrstuvwxyz

# Comma separated list of usernames of playlist authors.
# This allows you to back up other peoples playlists (that you follow) if you want.
# if left blank, all of your followed/created playlists will be backed up.
SPOTIFY_OWNER_IDS=snoopdogg,drdre,spotify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Run the script
&lt;/h2&gt;

&lt;p&gt;Once you have setup the &lt;code&gt;.env&lt;/code&gt; file, you're ready to run the script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python script.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This assumes you already have python installed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes, it is that easy. After running the above script you will have a local copy of all your playlist data in beautiful &lt;code&gt;json&lt;/code&gt; format.&lt;/p&gt;

&lt;h2&gt;
  
  
  Github Action setup
&lt;/h2&gt;

&lt;p&gt;Before your Github Action will run successfully, you must setup the above &lt;code&gt;.env&lt;/code&gt; variables correctly within the repo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make sure your fork is a private repository&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvb2ubljq48qsd0nbncsp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvb2ubljq48qsd0nbncsp.jpg" alt="Github actions dashboard screenshot" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cron Job
&lt;/h2&gt;

&lt;p&gt;Lets go one step further and set our Github Action to run once a week. By default, the CRON Job Github Action is disabled. To enable this within your repo, open the &lt;code&gt;.github/workflows/python-app.yml&lt;/code&gt; file and uncomment the schedule code block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# scheduled to run each week at 3am on a Tuesday&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;3&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;2'&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;logLevel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Log&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;level'&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;warning'&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;choice&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;info&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;warning&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;debug&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;You can use the &lt;a href="https://crontab.guru/" rel="noopener noreferrer"&gt;crontab&lt;/a&gt; tool to calculate when and how often you want to run the Github Action.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>welcome</category>
      <category>community</category>
    </item>
    <item>
      <title>Remove duplicate Objects within an Array by Object key.</title>
      <dc:creator>Luke Secomb</dc:creator>
      <pubDate>Sun, 16 Aug 2020 13:21:44 +0000</pubDate>
      <link>https://forem.com/lukethacoder/remove-duplicate-objects-within-an-array-by-object-key-5g3p</link>
      <guid>https://forem.com/lukethacoder/remove-duplicate-objects-within-an-array-by-object-key-5g3p</guid>
      <description>&lt;p&gt;A quick and easy way to remove duplicate Objects within an Array of Objects by key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;removeDuplicateObjectsByKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fieldToDuplicateCheck&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrayKeys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// check if we don't already have the value within the arrayKeys array&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;arrayKeys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fieldToDuplicateCheck&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// push this value to the arrayKeys array&lt;/span&gt;
      &lt;span class="nx"&gt;arrayKeys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fieldToDuplicateCheck&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
      &lt;span class="c1"&gt;// push this object to the newArray array&lt;/span&gt;
      &lt;span class="nx"&gt;newArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="c1"&gt;// return the newArray with the filtered out duplicate objects&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;newArray&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// A test array of objects. In a real world situation you would have more than just the 'name' key on the objects&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialArrayOfObjects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🐑&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🐑&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🐫&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🦕&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🦕&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;// will filter out the duplicates by the 'name' field&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;removeDuplicateObjects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;removeDuplicateObjectsByKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialArrayOfObjects&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// [ { name: '🐑' }, { name: '🐫' }, { name: '🦕' } ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://gist.github.com/lukethacoder/e45199df67514ec0d7576f6fd897a376" rel="noopener noreferrer"&gt;Github Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cover Photo Credits to &lt;a href="https://unsplash.com/@charlfolscher" rel="noopener noreferrer"&gt;Charl Folscher&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>[SOLVED] ACF not saving data after WP 5 update</title>
      <dc:creator>Luke Secomb</dc:creator>
      <pubDate>Mon, 04 May 2020 00:10:37 +0000</pubDate>
      <link>https://forem.com/lukethacoder/solved-acf-not-saving-data-after-wp-5-update-1jbk</link>
      <guid>https://forem.com/lukethacoder/solved-acf-not-saving-data-after-wp-5-update-1jbk</guid>
      <description>&lt;p&gt;If in doubt, duplicate your ACF Field group.&lt;/p&gt;

&lt;p&gt;In all seriousness, this should solve any issues regarding not being able to save posts with nested ACF fields &amp;amp; repeaters. &lt;/p&gt;

&lt;p&gt;If this does not work. Try adjusting the WP DB table &lt;code&gt;wp_options&lt;/code&gt; -&amp;gt; &lt;code&gt;option_name&lt;/code&gt; to a lower version. This will trigger the ACF DB update if needed.&lt;/p&gt;

&lt;p&gt;Cover image credits: &lt;a href="https://unsplash.com/@steadyhandco" rel="noopener noreferrer"&gt;@steadyhandco&lt;/a&gt;&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>acf</category>
    </item>
    <item>
      <title>SFDX: Good to know</title>
      <dc:creator>Luke Secomb</dc:creator>
      <pubDate>Thu, 02 Jan 2020 02:31:53 +0000</pubDate>
      <link>https://forem.com/lukethacoder/pull-push-and-deploy-sfdx-good-to-know-part-2-553m</link>
      <guid>https://forem.com/lukethacoder/pull-push-and-deploy-sfdx-good-to-know-part-2-553m</guid>
      <description>&lt;p&gt;How the heck do I set up a scratch org using sfdx? Well, you're in the right place.&lt;/p&gt;

&lt;p&gt;Firstly, you will need to have SFDX (&lt;a href="https://developer.salesforce.com/tools/sfdxcli" rel="noopener noreferrer"&gt;Salesforce CLI&lt;/a&gt;) installed and VS Code. You will also need your own Salesforce DevHub instance setup (need a hand with setting up your dev hub? check out this &lt;a href="https://trailhead.salesforce.com/en/content/learn/modules/sfdx_app_dev/sfdx_app_dev_setup_dx" rel="noopener noreferrer"&gt;trailhead unit&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a Salesforce DX Project
&lt;/h2&gt;

&lt;p&gt;The second step is to create a (SF)DX project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:project:create &lt;span class="nt"&gt;-n&lt;/span&gt; YOUR_PROJECT_NAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Auth your DevHub
&lt;/h2&gt;

&lt;p&gt;Next, we need to connect your DevHub with your new project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:auth:web:login &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; ALIAS_FOR_YOUR_DEV_HUB &lt;span class="nt"&gt;-r&lt;/span&gt; https://test.salesforce.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt; sets this as the default Dev Hub.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-a&lt;/code&gt; sets this alias for the org.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-r&lt;/code&gt; sets the login URL for the org.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have already auth'd, set your default username using &lt;code&gt;sfdx force:config:set defaultdevhubusername=lukesfakeemail@force.com&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Login To Sandboxes
&lt;/h2&gt;

&lt;p&gt;In addition to DebHubs, we can also connect to standard salesforce Sandboxes. This can be handy when it comes to pulling components into your scratch org&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:auth:web:login &lt;span class="nt"&gt;-r&lt;/span&gt; https://test.salesforce.com &lt;span class="nt"&gt;-a&lt;/span&gt; ALIAS_FOR_YOUR_SANDBOX
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Remember, don't use the &lt;code&gt;-d&lt;/code&gt; flag. If you do, the CLI thinks the org is your Dev Hub, and then you'll see an error when you try to create a scratch org.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If &lt;code&gt;force:auth:web:login&lt;/code&gt; isnt working, use &lt;code&gt;sfdx force:auth:device:login -r https://test.salesforce.com -a YOUR_ORG_ALIAS&lt;/code&gt; instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rename (add) Alias
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:alias:set &lt;span class="nv"&gt;NEW_ALIAS_FOR_YOUR_SANDBOX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;current@sandbox.user.com
sfdx force:alias:set &lt;span class="nv"&gt;OLD_ALIAS_FOR_YOUR_SANDBOX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Logout of Sandboxes
&lt;/h2&gt;

&lt;p&gt;logout/remove the sandbox from the &lt;code&gt;sfdx force:org:list&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:auth:logout &lt;span class="nt"&gt;-u&lt;/span&gt; ALIAS_FOR_YOUR_SANDBOX
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create your scratch org
&lt;/h2&gt;

&lt;p&gt;Now for the fun part, creating your scratch org.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;if you want to set the scratch org name, or adjust other config options, edit the &lt;code&gt;./config/project-scratch-def.json&lt;/code&gt; file before progressing&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:org:create &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; ALIAS_OF_YOUR_DEBHUB &lt;span class="nt"&gt;-f&lt;/span&gt; config/project-scratch-def.json &lt;span class="nt"&gt;-a&lt;/span&gt; ALIAS_FOR_SCRATCH_ORG &lt;span class="nt"&gt;-d&lt;/span&gt; 30 &lt;span class="nt"&gt;-w&lt;/span&gt; 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-v&lt;/code&gt; optional param to choose your DevHub (not needed if you have a default DevHub set)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-s&lt;/code&gt; sets this as the default sratch org&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-f&lt;/code&gt; sets the location for the config file (to build the org)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-a&lt;/code&gt; sets the alias for the scratch org&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt; sets the expiry to 30 days&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-w&lt;/code&gt; sets the wait time to 10mins&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you already scratch'd an org &lt;code&gt;sfdx force:config:set defaultusername=lukesfakeemail@force.com&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  View Scratch Org Config/Details
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:org:display &lt;span class="nt"&gt;-u&lt;/span&gt; SCRATCH_ORG_ALIAS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Generate Password Scratch Org
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:user:password:generate &lt;span class="nt"&gt;-u&lt;/span&gt; SCRATCH_ORG_ALIAS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Delete Scratch Org
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:org:delete &lt;span class="nt"&gt;-u&lt;/span&gt; SCRATCH_ORG_ALIAS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Assign Permission Set
&lt;/h2&gt;

&lt;p&gt;Before you can start pushing code, we have to set up some permission sets to allow us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:user:permset:assign &lt;span class="nt"&gt;-n&lt;/span&gt; NAME_OF_PERMISSION_SET
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;most likely named &lt;code&gt;SalesConsoleUser&lt;/code&gt; on default scratch orgs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Fetch all Metadata from an Org (Metadata API)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: we are using the sfdx-ext plugin which can be found &lt;a href="https://github.com/brianedwardsaunders/sfdx-ext" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fetch the Metadata&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx ext:mdapi:retrieve &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; SOURCE_ORG_NAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Convert the source to Metadata API (instead of Source API)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx ext:mdapi:convert &lt;span class="nt"&gt;--sourcedirectory&lt;/span&gt; src &lt;span class="nt"&gt;--targetdirectory&lt;/span&gt; ./
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean up the Source API folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; src
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If any of this falls over, you may need to either update the &lt;code&gt;sfdx-ext&lt;/code&gt; plugin or remove un-parsable files.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Deploy code back to DevHub
&lt;/h2&gt;

&lt;p&gt;Deploy all of type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:source:deploy &lt;span class="nt"&gt;-m&lt;/span&gt; ApexPage, ApexClasses, LightningComponentBundle &lt;span class="nt"&gt;-u&lt;/span&gt; ALIAS_FOR_YOUR_DEV_HUB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy specific component by path&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:source:deploy &lt;span class="nt"&gt;-p&lt;/span&gt; force-app/main/default/lwc/SINGLE_COMPONENT_NAME &lt;span class="nt"&gt;-u&lt;/span&gt; ALIAS_FOR_YOUR_DEV_HUB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fetch / Pull Data
&lt;/h2&gt;

&lt;p&gt;Retrieve All ApexClasses, ApexPages, LWC's&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:source:retrieve &lt;span class="nt"&gt;-m&lt;/span&gt; ApexClass, ApexPage, LightningComponentBundle &lt;span class="nt"&gt;-u&lt;/span&gt; ALIAS_FOR_YOUR_DEV_HUB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_types_list.htm" rel="noopener noreferrer"&gt;Metadata Ref&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create / Import Data
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;data can be retrieved from a sandbox using &lt;code&gt;sfdx force:source:retrieve -m CustomObject -u SANDBOX_SOURCE_ORG&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Create Data
&lt;/h2&gt;

&lt;p&gt;Specify the Object type and the fields 'n values&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:data:record:create &lt;span class="nt"&gt;-s&lt;/span&gt; Account &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"Name='Marriott Marquis' BillingStreet='780 Mission St' BillingCity='San Francisco' BillingState='CA' BillingPostalCode='94103' Phone='(415) 896-1600' Website='www.marriott.com'"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Export Data
&lt;/h4&gt;

&lt;p&gt;Using SQL to JSON data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:data:tree:export &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"SELECT Name, BillingStreet, BillingCity, BillingState, BillingPostalCode, Phone, Website FROM Account WHERE BillingStreet != NULL AND BillingCity != NULL and BillingState != NULL&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; -d ./data
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Import Data
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:data:tree:import &lt;span class="nt"&gt;--sobjecttreefiles&lt;/span&gt; data/Account.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create an Apex Class
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sfdx force:apex:class:create &lt;span class="nt"&gt;-n&lt;/span&gt; YourControllerName &lt;span class="nt"&gt;-d&lt;/span&gt; force-app/main/default/classes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;config/project-scratch-def.json&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Disable Lightning Experience caching&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"settings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"orgPreferenceSettings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"s1EncryptedStoragePref2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Disabling secure and persistent browser caching has a significant negative performance impact on Lightning Experience. Always enable the setting in production orgs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Useful Commands
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;See config options &lt;code&gt;sfdx force:config:set -h&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;See all commands &lt;code&gt;sfdx force:doc:commands:list&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Refresh SObject cache for VS Code intellisense &lt;code&gt;sfdx sobject definitions refresh -u SCRATCH_ORG_USERNAME&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>salesforce</category>
      <category>lwc</category>
      <category>sfdx</category>
      <category>apex</category>
    </item>
    <item>
      <title>SFDX Good to know - Scratch Orgs (PART 1)</title>
      <dc:creator>Luke Secomb</dc:creator>
      <pubDate>Tue, 17 Dec 2019 11:00:13 +0000</pubDate>
      <link>https://forem.com/lukethacoder/sfdx-good-to-know-scratch-orgs-part-1-3jjc</link>
      <guid>https://forem.com/lukethacoder/sfdx-good-to-know-scratch-orgs-part-1-3jjc</guid>
      <description>&lt;p&gt;How the heck do I set up a scratch org using sfdx? Well, you're in the right place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparation
&lt;/h2&gt;

&lt;p&gt;Firstly, you will need to have SFDX (&lt;a href="https://developer.salesforce.com/tools/sfdxcli" rel="noopener noreferrer"&gt;Salesforce CLI&lt;/a&gt;) installed and VS Code. You will also need your own Salesforce DevHub instance setup (need a hand with setting up your dev hub? check out this &lt;a href="https://trailhead.salesforce.com/en/content/learn/modules/sfdx_app_dev/sfdx_app_dev_setup_dx" rel="noopener noreferrer"&gt;trailhead unit&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a Salesforce DX Project
&lt;/h2&gt;

&lt;p&gt;Ok, now we are setup lets get into it. The first step is to create an (SF)DX project.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sfdx force:project:create -n YOUR_PROJECT_NAME&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Auth your DevHub
&lt;/h2&gt;

&lt;p&gt;Next, we need to connect our DevHub with the new project&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sfdx force:auth:web:login -d -a ALIAS_FOR_YOUR_DEV_HUB&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt; sets this as the default Dev Hub. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-a&lt;/code&gt; sets this alias for the org. (strongly recommended)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have already auth'd, set your default username using &lt;code&gt;sfdx force:config:set defaultdevhubusername=lukesfakeemail@force.com&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h4&gt;
  
  
  Login To Sandboxes
&lt;/h4&gt;

&lt;p&gt;In addition to DebHubs, we can also connect to standard Salesforce Sandboxes. This can be handy when it comes to pulling components into your scratch org&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sfdx force:auth:web:login -r https://test.salesforce.com -a ALIAS_FOR_YOUR_SANDBOX&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You may also choose to change the default &lt;code&gt;https://test.salesforce.com&lt;/code&gt; url to a custom domain if you have set one up.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Remember, don’t use the &lt;code&gt;-d&lt;/code&gt; flag. If you do, the CLI thinks the org is your Dev Hub, and then you’ll see an error when you try to create a scratch org. &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Create your scratch org
&lt;/h2&gt;

&lt;p&gt;Now for the fun part, creating your scratch org.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;if you want to set the scratch org name, or adjust other config options, edit the &lt;code&gt;./config/project-scratch-def.json&lt;/code&gt; file before progressing. Later in this series we will properly cover the cool things we can achieve using the &lt;code&gt;project-scratch-def.json&lt;/code&gt; file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;sfdx force:org:create -s -f config/project-scratch-def.json -a ALIAS_FOR_SCRATCH_ORG -d 30 -w 10&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-s&lt;/code&gt; sets this as the default sratch org&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-f&lt;/code&gt; sets the location for the config file (to build the org)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-a&lt;/code&gt; sets the alias for the scratch org&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt; sets the expiry to 30 days&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-w&lt;/code&gt; sets the wait time to 10mins&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you already scratch'd an org &lt;code&gt;sfdx force:config:set defaultusername=lukesfakeemail@force.com&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Assign Permission Set
&lt;/h3&gt;

&lt;p&gt;Before you can start pushing code, we have to set up some permission sets to allow us.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sfdx force:user:permset:assign -n NAME_OF_PERMISSION_SET&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;most likely named &lt;code&gt;SalesConsoleUser&lt;/code&gt; on default scratch orgs&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;And there we have it, you've successfully setup a new SFDX Project and connected it to a scratch org. In part 2 we will check out how we can push&lt;/p&gt;




&lt;h3&gt;
  
  
  TL:DR Commands
&lt;/h3&gt;

&lt;p&gt;create new sfdx project&lt;br&gt;
&lt;code&gt;sfdx force:project:create -n YOUR_PROJECT_NAME&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;auth a devhub&lt;br&gt;
&lt;code&gt;sfdx force:auth:web:login -d -a ALIAS_FOR_YOUR_DEV_HUB&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;login to a sandbox&lt;br&gt;
&lt;code&gt;sfdx force:auth:web:login -r https://test.salesforce.com -a ALIAS_FOR_YOUR_SANDBOX&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;create a new scratch org&lt;br&gt;
&lt;code&gt;sfdx force:org:create -s -f config/project-scratch-def.json -a ALIAS_FOR_SCRATCH_ORG -d 30 -w 10&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;assign a permission set&lt;br&gt;
&lt;code&gt;sfdx force:user:permset:assign -n SalesConsoleUser&lt;/code&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>CSS Syntax Highlighting in IntelliJ</title>
      <dc:creator>Luke Secomb</dc:creator>
      <pubDate>Thu, 20 Jun 2019 04:51:47 +0000</pubDate>
      <link>https://forem.com/lukethacoder/css-syntax-highlighting-in-intellij-5ac6</link>
      <guid>https://forem.com/lukethacoder/css-syntax-highlighting-in-intellij-5ac6</guid>
      <description>&lt;p&gt;Out of the box IntelliJ has no syntax highlighting for *.css files.&lt;/p&gt;

&lt;p&gt;Nothing a simple settings change can't fix.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Settings -&amp;gt; Editor -&amp;gt; File Types&lt;/code&gt; and change the &lt;code&gt;*.css&lt;/code&gt; file association from &lt;code&gt;CSS (syntax Highlighting Only)&lt;/code&gt; to &lt;code&gt;CSS Files (Improved Syntax Highlighting&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fafrd4u5w4uv22g8ec543.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fafrd4u5w4uv22g8ec543.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>css</category>
      <category>intellij</category>
      <category>ide</category>
    </item>
    <item>
      <title>Use Custom HTML Attribute's in TypeScript</title>
      <dc:creator>Luke Secomb</dc:creator>
      <pubDate>Thu, 13 Jun 2019 14:31:50 +0000</pubDate>
      <link>https://forem.com/lukethacoder/use-custom-html-attribute-s-in-typescript-2co</link>
      <guid>https://forem.com/lukethacoder/use-custom-html-attribute-s-in-typescript-2co</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@hnyuuu" rel="noopener noreferrer"&gt;Ningyu He&lt;/a&gt; on Unsplash&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Installing different packages and frameworks means you run into some interesting problems with TypeScript. One recently was using custom HTML Attributes on DOM elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;HTMLAttributes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;AriaAttributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DOMAttributes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// extends React's HTMLAttributes&lt;/span&gt;
    &lt;span class="nx"&gt;custom&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This piece of code solved my issue, and allows you to add any custom HTML attributes when using TypeScript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;custom=&lt;/span&gt;&lt;span class="s"&gt;"no_ts_errors"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  your content here
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>typescript</category>
      <category>react</category>
      <category>todayisearched</category>
      <category>showdev</category>
    </item>
    <item>
      <title>SASS in Lightening Web Components? (Salesforce Devs)</title>
      <dc:creator>Luke Secomb</dc:creator>
      <pubDate>Thu, 13 Jun 2019 14:23:57 +0000</pubDate>
      <link>https://forem.com/lukethacoder/sass-in-lightening-web-components-salesforce-devs-51ki</link>
      <guid>https://forem.com/lukethacoder/sass-in-lightening-web-components-salesforce-devs-51ki</guid>
      <description>&lt;p&gt;Is it possible to (nicely) use SASS (or similar css compiler) within the Salesforce lightening web components ecosystem?&lt;/p&gt;

&lt;p&gt;And no, Salesforce Lightning Design System is not the answer.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>help</category>
      <category>salesforce</category>
      <category>saas</category>
    </item>
  </channel>
</rss>
