{"id":13545933,"url":"https://github.com/tsalb/intro-to-lwc","last_synced_at":"2025-04-02T17:32:21.249Z","repository":{"id":37647905,"uuid":"245909047","full_name":"tsalb/intro-to-lwc","owner":"tsalb","description":"Hyper fast intro to LWC fundamentals to supplement the official LWC docs, Trailheads and MDN","archived":false,"fork":false,"pushed_at":"2021-02-24T07:42:52.000Z","size":226,"stargazers_count":79,"open_issues_count":0,"forks_count":10,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-08-01T12:11:09.041Z","etag":null,"topics":["lightning-web-components","lwc","salesforce","salesforce-developers","salesforce-lightning","sfdx"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tsalb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-09T00:10:53.000Z","updated_at":"2024-07-03T06:44:17.000Z","dependencies_parsed_at":"2022-09-04T15:12:57.691Z","dependency_job_id":null,"html_url":"https://github.com/tsalb/intro-to-lwc","commit_stats":null,"previous_names":["tsalb/intro-to-lwcs"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsalb%2Fintro-to-lwc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsalb%2Fintro-to-lwc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsalb%2Fintro-to-lwc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tsalb%2Fintro-to-lwc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tsalb","download_url":"https://codeload.github.com/tsalb/intro-to-lwc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246860202,"owners_count":20845630,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lightning-web-components","lwc","salesforce","salesforce-developers","salesforce-lightning","sfdx"],"created_at":"2024-08-01T12:00:27.375Z","updated_at":"2025-04-02T17:32:20.956Z","avatar_url":"https://github.com/tsalb.png","language":"HTML","funding_links":[],"categories":["Want to learn On Platform LWC?"],"sub_categories":["JEST related posts"],"readme":"##  Intro to LWCs\n\nMany people want to start with writing LWCs but have a hard time finding where to start (even with the Trailheads). This resource serves as fundamental knowledge to supplement other resources.\n\nYou can treat this resource as an index of nouns and table of contents for all the self-learning you will need to do by yourself to get fully up to speed on LWC.\n\n## How to get started using this repo?\n\n1) Install [Salesforce CLI](https://developer.salesforce.com/docs/atlas.en-us.224.0.sfdx_setup.meta/sfdx_setup/sfdx_setup_install_cli.htm#sfdx_setup_install_clihttps://developer.salesforce.com/tools/sfdxcli).\n2) Install VS Code and [Salesforce Extensions for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode).\n3) Install [Git](https://git-scm.com/downloads).\n4) [Set up](https://help.github.com/articles/set-up-git/) Git.\n5) Familiarize yourself VSCode Quick Start Trailhead [Module](https://trailhead.salesforce.com/content/learn/projects/quickstart-vscode-salesforce).\n6) Open VSCode's terminal and navigate to a directory where you want to clone this repo:\n    - MacOs / Windows: Ctrl+`\n    - Run `git clone https://github.com/tsalb/intro-to-lwcs.git` to your desired directory.\n7) Using VSCode, File =\u003e Open the `intro-to-lwc` folder that was just cloned.\n8) Authorize your sandbox / trailhead sandbox using `SFDX: Authorize an Org` in the command palette.\n    - MacOs: Cmd+Shift+P\n    - Windows: Ctrl+Shift+P\n    - Sandbox =\u003e Any alias (something easy to type) =\u003e Enter =\u003e Provide credentials\n9) If it didn't already set, at the bottom of VSCode click on `No Default Org Set` and choose the sandbox you had just authed into.\n10) In the File Explorer, navigate to the `manifest` folder and right click the `package.xml` and do `SFDX: Deploy Source in Manifest to Org`.\n\nWe will be using the [Org Development Model](https://developer.salesforce.com/tools/vscode/en/user-guide/development-models/#org-development-model) nouns such as `deploy` and `retrieve` in the this guide.\n\n## Scan the Lessons Learned wiki\n\n\u003e Note: From when this repo was created to now (`2021-02-23`), there are no new fundamentals to LWCs at the intro level.\n\nThat being said, I have compiled a list of resources and breadcrumbs of knowledge that can help you on your LWC learning journey in the [Lessons Learned](https://github.com/tsalb/intro-to-lwc/wiki#lessons-learned) wiki entry. Please keep these tidbits of information in mind as you learn LWC!\n\nThey contain, for example:\n- How to manage your `sfdx-cli` installation.\n- What are popular, free, resources to start reading about Modern JS.\n- Useful ES6 functions.\n- High level mental models for LWC approach on solution design.\n\n## Why Org Development Model?\n\nIf you're using scratch orgs in your day to day, it's likely you're already familiar with the sfdx-cli. So then, you can translate the lwc specific knowledge here to the `pull` and `push` model.\n\nMost Lightning orgs out there are unlikely to be net new implementations so a roadmap to move from the Metadata API project structure to the SFDX project structure is necessary. In my experience, the middle ground is an **sfdx project created with a manifest** connected to a sandbox.\n\nThis is the fastest way to start producing LWCs. This is also likely the most popular way since there are still some slight gaps within the scratch org process for truly complex orgs to fully adopt them (without extra scripting) as part of their SDLC.\n\n## What about Aura?\n\nMigration strategy and comparison will not be covered. I have other repos that you can look at to get into that [here](https://github.com/tsalb/lwc-utils).\n\nAs much as both Salesforce won't admit and you dont wan't to, there are still situations where you will still need to reach back into Aura on an as-needed basis for base components that are not found in LWC.\n\nWe won't be covering those here.\n\n## Browser and General JS Knowledge\n\nLWC follows web standards adopted by most major browsers. That means that a lot of the framework you see is actually just an abstraction layer on top of the JS engine that lives inside most major browsers. This is what LWC-Open Source (LWC-OSS) is. On-Platform LWC (LWC) is a few steps behind LWC-OSS because standards and conventions get hardened there first and then adopted into the platform.\n\nThe LWC team is doing a good job this time around making sure developers don't shoot themselves in the foot and that all incoming RFCs are hardened before released globally on platform. Since Salesforce promises to support backwards compatibility ad-infinitum, anything they release cannot *usually* be backed out. I think it's a pretty good model and if you're interested in sneak-peak of *possible* features, just follow the LWC-OSS [github repo](https://github.com/salesforce/lwc) and the accompanying [rfc repo](https://github.com/salesforce/lwc-rfcs/pulls).\n\nWhat this means is that learning LWC is really just learning JS first. [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript) is now your primary documentation for all JS knowledge and the [LWC docs](https://developer.salesforce.com/docs/component-library/documentation/en/48.0/lwc) inside the component library are all LWC specific things. However, not all browser JS can be used in an LWC. That is what the [Locker API prevents](https://developer.salesforce.com/docs/component-library/tools/locker-service-viewer).\n\nAnd if it wasn't confusing enough, another layer of security alongside Locker is the [Shadow DOM](https://developer.salesforce.com/docs/component-library/documentation/en/48.0/lwc/create_dom). You won't typically hit issues this if you follow the best practices per the official docs. Shadow DOM is part of the browser spec, but the LWC framework uses something called a `synthetic-shadow` which aims to plug gaps from the current browser's implementation of the Shadow DOM.\n\nThe **tl;dr;** for Shadow DOM is that the LWC framework mostly deals with this and won't let you reach into another LWC to look at its contents or data unless that LWC *explicitly* allows you to do so via the `@api` decorator.\n\n[More reading on Web Components and Shadow DOM in general](https://developer.mozilla.org/en-US/docs/Web/Web_Components)\n\n## Org Caching and CDN\n\nThe platform aggressively caches things like LWCs which is useful in production to speed up the user experience. However, it's not so great for development when you want to see rapid changes you make to a sandbox.\n\nMake sure these settings are **disabled** (unchecked):\n\n```\nSetup \u003e Security \u003e Session Settings \u003e Caching\n- Enable secure and persistent browser caching to improve performance\n- Enable Content Delivery Network (CDN) for Lightning Component framework\n```\n\n## Fundamentals of LWC\n\n### 1) Naming conventions and what goes into an LWC bundle\n\nThere are two types of naming conventions for LWC: `kebab-case` and `camelCase`.\n\nThe LWC files themselves are `camelCase` with a bundle that looks like this: \n\n```\nmyComponent\n├──myComponent.html\n├──myComponent.js\n├──myComponent.js-meta.xml\n├──myComponent.css\n└──myComponent.svg\n```\nThe more detailed rules are [here](https://developer.salesforce.com/docs/component-library/documentation/en/48.0/lwc/lwc.create_components_folder).\n\nThe actual `myComponent.js` file would use the following `MyComponent` constructor. Notice the capitalized `M`.\n\n```javascript\nimport { LightningElement } from 'lwc';\nexport default class MyComponent extends LightningElement {\n    \n}\n```\n\nIf you were to use this component available to be used in another one, you need to use a namespace, `c` by default, and then flip it to `kebab-case` as such:\n\n```html\n\u003c!-- anotherComponent.html --\u003e\n\u003cc-my-component\u003e\u003c/c-my-component\u003e\n```\n\nConfusing? Yes. Will you get use to it? Yes.\n\n### 2) Reactive properties and Decorators\n\nThe framework handles the abstraction for reactivity natively. All properties referenced in the `template` (the html file) are by default reactive. This just means that if a new value changes in the JS controller, the `template` will automatically see those changes. It is *reactive*.\n\nDecorators `@api` and `@wire` are abstractions which tell the framework that there is something special about properties *decorated* by those pieces of text. We will get into the `@wire` decorator later. `@api` exposes the attribute for use, both setting and getting of values, by other components.\n\n```html\n\u003c!-- item.html --\u003e\n\u003ctemplate\u003e\n    \u003cdiv\u003e\n        \u003clabel\u003e{itemName}\u003c/label\u003e\n    \u003c/div\u003e\n\u003c/template\u003e\n```\n```javascript\n// item.js\nimport { LightningElement, api } from 'lwc';\n\nexport default class Item extends LightningElement {\n    @api itemName = 'New Item';\n}\n```\n\nBut this example in itself isn't useful nor a good example of what `@api` does. Here's an example of how to compose `\u003cc-item\u003e` into something useful and adding in a *bound* property, `parentSuppliedName`.\n\n```html\n\u003c!-- storeFront.html --\u003e\n\u003ctemplate\u003e\n    \u003clightning-card\u003e\n        \u003cdiv slot=\"actions\"\u003e\n            \u003clightning-input onkeyup={inputKeyUp}\u003e\u003c/lightning-input\u003e\n        \u003c/div\u003e\n        Parent Supplied Name: {parentSuppliedName}\n        \u003cc-item item-name=\"Milk\"\u003e\u003c/c-item\u003e\n        \u003cc-item item-name=\"Eggs\"\u003e\u003c/c-item\u003e\n        \u003cc-item item-name={parentSuppliedName}\u003e\u003c/c-item\u003e\n        \u003c!-- No props set means fallback to what's in child component --\u003e\n        \u003cc-item\u003e\u003c/c-item\u003e\n    \u003c/lightning-card\u003e\n\u003c/template\u003e\n\n```\n```javascript\n// storeFront.js\nimport { LightningElement } from 'lwc';\n\nexport default class StoreFront extends LightningElement {\n    parentSuppliedName;\n\n    inputKeyUp(evt) {\n        this.parentSuppliedName = evt.target.value.toUpperCase();\n    }\n}\n```\n\nTo make this droppable onto a record page:\n\n```xml\n\u003c!-- storeFront.js-meta.xml --\u003e\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cLightningComponentBundle xmlns=\"http://soap.sforce.com/2006/04/metadata\"\u003e\n    \u003capiVersion\u003e48.0\u003c/apiVersion\u003e\n    \u003cisExposed\u003etrue\u003c/isExposed\u003e\n    \u003cmasterLabel\u003eStore Front\u003c/masterLabel\u003e\n    \u003ctargets\u003e\n        \u003ctarget\u003elightning__RecordPage\u003c/target\u003e\n    \u003c/targets\u003e\n\u003c/LightningComponentBundle\u003e\n```\n\n\u003e**Important Note**: You only need the `@track` decorator now for tracking data within a collection or JS object. In other words, most of the time you don't need it unless you're doing more advanced data manipulation/assignment in JS. \n\n### Hands on exercises and next section(s)\n\nStarting from here, the rest of this tutorial and any hands-on will be nested under each branch like so:\n\n```\nmaster\n- exercise-1\n- exercise-2\n- exercise-3\n...\n```\nWhy do this? It's easier to change some of the repo code this way so that you can always `deploy` it to your sandbox.\n\n[Click here to go to the next section](https://github.com/tsalb/intro-to-lwcs/tree/exercise-1#3-event-driven).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsalb%2Fintro-to-lwc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftsalb%2Fintro-to-lwc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftsalb%2Fintro-to-lwc/lists"}