@lwrjs/everywhere v0.14.4
LWR Everywhere
- Displaying components
- Interactivity
- Connected App setup
- Build your own LWR Everywhere module
- API reference
LWR Everywhere allows you to embed Lightning web components into your web page or app using just a few lines of code. LWR Everywhere is powered by the Lightning Web Stack, which provides:
- full use of the Lightning Web Components framework
- out-of-the-box security with Lightning Web Security
- support for the Salesforce Lightning Design System (SLDS)
- UI API adapter integration
Displaying components
This section goes through the steps to display a Lightning web component on your website. No special tools or setup needed!
1. Add a container to the HTML
First, open the HTML page you want to edit. Add an empty <div>
tag anywhere within the <body>
to mark where you want to display a Lightning web component. For example:
<!-- ... existing HTML ... -->
<div id="embed-stats"></div>
<!-- ... existing HTML ... -->
This <div>
has a unique id
attribute. This allows us to find it later so we can embed a component in it.
2. Import the LWR Everywhere Module
Add a JavaScript module script to the HTML page. For example:
<script type="module" src="lwre.js"></script>
Import the authenticate
and createComponent
APIs from the LWR Everywhere module. For example:
// lwre.js
// Import the LWR Everywhere module
import { authenticate, createComponent } from 'https://lwr-server.com/resource/path/lwr-everywhere.js';
Tip: Use a minified version of the LWR Everywhere module by importing
lwr-everywhere-min.js
and a debug version withlwr-everywhere-debug.js
.
3. Authenticate
In order to access components from your Salesforce org, you must be authenticated. LWR Everywhere doesn’t handle authentication, so you must provide it with a Salesforce authentication token and instance URL. For example:
// lwre.js
import { authenticate, createComponent } from 'https://lwr-server.com/resource/path/lwr-everywhere.js';
const { access_token, instance_url } = getAuthData(); // you write this logic
authenticate({ access_token, instance_url });
Note: The authentication data is obtained from an OAuth flow into your Connected App.
4. Display a component
After authenticating, embed a Lightning web component on your website. For example:
// lwre.js
import { authenticate, createComponent } from 'https://lwr-server.com/resource/path/lwr-everywhere.js';
const { access_token, instance_url } = getAuthData();
authenticate({ access_token, instance_url });
createComponent('my/stats', 'embed-stats', { category: 'cats', darkMode: true });
And that's it!
This one line of code displays the "my/stats" component in the <div>
we created in the first step, and passes in some public properties (category
and darkMode
).
Tip: Check out the API reference for
authenticate
andcreateComponent
.
Interactivity
After creating a component, you can interact with it.
Update component properties
Update a component's public properties to add reactivity. For example:
const container = document.querySelector('#counter-container');
const counter = createComponent('my/counter', container, { count: 6 });
// ... time passes ...
counter.properties = { count: 9 };
Client-side Navigation
If the embedded component uses the LWR Client-side Router, turn on the navigation
setting. Then you can navigate programmatically and subscribe to navigation events and errors. For example:
import { createComponent } from 'https://lwr-server.com/resource/path/lwr-everywhere.js';
const cmp = createComponent('my/cmp', 'container', { mode: 'compact' }, { navigation: true });
// Navigate by updating the current page reference
cmp.pageReference = { type: 'standard__namedPage', attributes: { pageName: 'home' } };
// Subscribe to navigation events and errors
cmp.addEventListener('navigate', ({ detail }) => {
console.log('Navigated to page reference:', detail);
});
cmp.addEventListener('navigationerror', ({ detail: { code, message } }) => {
console.error(`Navigation error: ${code} - ${message}`);
});
UI API Adapters
Important: This feature is currently under construction!
LWR Everywhere supports the UI API adapters. For example, this code shows an embedded component requesting a list of Opportunities from a Salesforce org via the getListInfoByName
wire:
import { LightningElement, wire } from 'lwc';
import { getListInfoByName } from 'lightning/uiListApi';
export default class MyData extends LightningElement {
opportunities = [];
@wire(getListInfoByName, {
objectApiName: 'Opportunity',
listViewApiName: 'AllOpportunities',
})
listView({ error, data }): void {
if (data) {
this.opportunities = data.records.records;
} else if (error) {
console.error(`Failed to fetch Opportunities: ${error.body.message}`);
}
}
}
Connected App setup
To enable authentication with LWR Everywhere, follow these steps to set up a secure Connected App:
- Create a Connected App with OAuth Settings using these instructions and:
- If a client-side authentication flow is being used, set the "Callback URL" to the URL of the HTML page (e.g.
"https://my-website.com/page"
) - Make a note of the "Consumer Key" and "Consumer Secret" (if applicable)
- Under Setup -> Manage Connected Apps, click "Edit" for the app and set "Permitted Users" to "Admin approved users are pre-authorized" and "Save"
- Approve Profiles for Connected App access:
- Go to Setup -> Profiles
- Select the desired Profile and click "Assigned Connected Apps"
- Add the Connected App to the "Enabled Connected Apps" list and click "Save"
- If a client-side authentication flow is being used, set the "Callback URL" to the URL of the HTML page (e.g.
- Enabled CORS for the website, if a client-side authentication flow is being used:
- Go to Setup -> CORS
- Add a new "Allowed Origin" for the website (e.g.
"https://my-website.com"
)
- Setup a Content Security Policy (CSP)
- Add a
script-src
CSP to the web page containing the Connected App origin, and'unsafe-eval'
to support Lightning Web Security. For example:
<meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-eval' https://connected-app-server.com" />
- Add a
Build your own LWR Everywhere module
For the majority of use cases, you simply import the LWR Everywhere Module from your Salesforce org. However, you can also generate your own custom LWR Everywhere module and host it yourself. For example:
// Import my custom LWR Everywhere module
import { authenticate, createComponent } from './static/my-lwr-everywhere.js';
Use the generate()
API from the @lwrjs/everywhere/generate
server module to build the file. For example:
// my-package/scripts/generate-client-runtime.mjs
import { generate } from '@lwrjs/everywhere/generate';
generate({
format: 'amd', // this is the only required option
server: 'https://lwr-server.com',
apiVersion: 'v57.0',
apiPrefix: '/lwr',
locale: 'fr',
bundle: false,
debug: true,
minify: true,
outFile: 'static-site/public/lwrEverywhere.js',
})
.then(() => {
console.log('>> successfully built the LWR Everywhere module');
process.exit(0);
})
.catch((e) => {
console.error('>> ERROR generating the LWR Everywhere module:', e);
process.exit(1);
});
Tip: Check out the API reference for
generate
.
API reference
Client APIs
Import these functions from the LWR Everywhere Module.
authenticate
interface AuthData {
access_token: string;
instance_url: string;
}
type AuthenticateFunction = (authData?: AuthData) => void;
createComponent
type CreateComponentFunction = (
specifier: string, // component specifier: "namespace/name" OR versioned: "namespace/name/v/2.0"
nodeId: string | HTMLElement, // either a DOM node or its id
properties: Record<string, any>, // default: {}
config: { navigation: boolean }, // default { navigation: false }
) => Promise<EverywhereComponent>;
interface EverywhereComponent extends Element {
properties: Record<string, any>; // update a component's public properties
pageReference?: PageReference; // update the current page reference in the LWR Router
}
interface PageReference {
type: string;
attributes?: Record<string, string | null>;
state?: Record<string, string | null>;
}
Server APIs
Import these functions from @lwrjs/everywhere/generate
.
generate
interface GenerationOptions {
// Required options
format: 'esm' | 'amd'; // format for component code, LWR-S only supports 'amd'
// Optional
server?: string; // LWR server origin, default: import.meta.url
apiVersion?: string; // LWR API version (eg: 'v57.0'), default: '1'
apiPrefix?: string; // LWR API prefix (eg: '/lwr'), default: ''
locale?: string; // default: LWR server default locale
bundle?: boolean; // bundle the component code if true, default: true
debug?: boolean; // use debug mode if true, default: false
// File options, relative paths appended to the CWD
minify?: boolean; // minify the module code if true, default: false
outFile?: string; // the module output file path, default: '__lwr_client__/lwr-everywhere.js'
}
type GenerateFunction = (options: GenerationOptions) => Promise<void>;
9 months ago
9 months ago
9 months ago
8 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
1 year ago
1 year ago
11 months ago
11 months ago
12 months ago
12 months ago
12 months ago
12 months ago
11 months ago
11 months ago
11 months ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago