loadScript or loadStyle. They are version-controlled, cached by the browser, and are the only approved way to bring third-party libraries into your org securely.
๐ Key Points
- Static Resources store files locally inside your Salesforce org and serve them from Salesforce's built-in Content Delivery Network (CDN).
- They are the officially approved method for integrating third-party libraries (like Chart.js or D3.js) into LWC, Aura, or Visualforce.
- Unlike remote
<script>tags, Static Resources do not require configuring Content Security Policy (CSP) Trusted Sites. - Use
platformResourceLoaderwithin a guardedrenderedCallbackto initialize the files. - Cache control limits (Public vs. Private) dictate how the browser stores the file.
chartjs.zip, upload it to Salesforce as a Static Resource, and load it into your LWC using loadScript(this, CHARTJS) inside the renderedCallback. The file is versioned with your deployment, safely cached by the browser, and the CSP never throws an error.
๐ ️ How to Load a Static Resource in LWC
To safely load an external script, import the resource, utilize the platformResourceLoader, and ensure you place a "guard" inside the renderedCallback so the file doesn't reload infinitely.
// 1. Import the loadScript utility and the Static Resource
import { loadScript } from 'lightning/platformResourceLoader';
import CHARTJS from '@salesforce/resourceUrl/chartjs';
import { LightningElement } from 'lwc';
export default class ChartComponent extends LightningElement {
_loaded = false; // The guard flag
// 2. renderedCallback runs after EVERY render
renderedCallback() {
// 3. The Guard: Stop execution if the library is already loaded
if (this._loaded) {
return;
}
this._loaded = true;
// 4. Load the script by appending the specific file path inside the ZIP
loadScript(this, CHARTJS + '/chart.min.js')
.then(() => {
this.initChart(); // Initialize library after successful load
})
.catch(error => {
this.error = error;
console.error('Error loading ChartJS', error);
});
}
initChart() {
// Logic to build your chart goes here
}
}
๐งญ 360 Card: Static Resource Strategy
- Rule: Third-party assets must live in the org as a Static Resource, never via an external CDN URL.
- Gain: You bypass CSP Trusted Site requirements, utilize Salesforce’s native CDN caching, and your assets are versioned alongside your metadata deployments.
- Price: You are entirely responsible for upgrades. When the library updates, you must perform a metadata deployment rather than simply pointing to a new URL.
- Limits: When loading inside
renderedCallback, you must use a boolean guard variable. Without it, the script will reload endlessly. - Mirror (The bad way): Using a remote script tag requires CSP exceptions, creates vulnerability to external server outages, and is frequently blocked by Lightning Web Security (LWS).
๐ก Core Q&A & Self-Check
If you use a remote script, you are forced to add the external URL to your CSP Trusted Sites, and if the external server goes down, your component breaks. By uploading the library as a Static Resource, you bundle the dependency directly into your Salesforce org. You implement this by importing the resource URL and calling loadScript inside the renderedCallback. Because the callback runs on every render, you must wrap the loadScript call in an if(!this._loaded) guard statement to prevent an infinite loading loop.
Static resources with Public cache-control are aggressively cached by the Salesforce CDN and the user's browser. If you simply overwrite the file, the browser will continue to serve the stale cached version until its Time-To-Live (TTL) expires. The best practice is to use path versioning. Upload the new file with a distinct name (e.g., chartjs_v2) and update your LWC import statement. Because the URL path physically changes, the browser is forced to pull the new file immediately. If it's an internal asset that changes constantly, change the cache-control to Private to shorten the caching lifespan.
To reference a specific file inside an uploaded ZIP archive, simply append the internal file path to the imported resource URL (e.g., RESOURCE_URL + '/images/logo.png').
Trade-off: A ZIP file is excellent for bundling cohesive assets (like a JS library and its required CSS file) into a single, clean deployment. However, you cannot set separate cache controls for individual files inside a ZIP, and updating a single icon requires re-uploading the entire ZIP archive. Upload files as a ZIP if they version together, but use separate resources for assets that update independently.