
Security News
Crates.io Users Targeted by Phishing Emails
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
@lwrjs/everywhere
Advanced tools
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:
This section goes through the steps to display a Lightning web component on your website. No special tools or setup needed!
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.
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
.
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.
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
.
After creating a component, you can interact with it.
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 };
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}`);
});
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}`);
}
}
}
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:
"https://my-website.com/page"
)Enabled CORS for the website, if a client-side authentication flow is being used:
"https://my-website.com"
)Setup a Content Security Policy (CSP)
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"
/>
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
.
Import these functions from the LWR Everywhere Module.
authenticate
interface AuthData {
access_token?: string; // optional, an Authorization header is sent if the token exists
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>;
}
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>;
FAQs
LWR Everywhere
We found that @lwrjs/everywhere demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
Product
Socket now lets you customize pull request alert headers, helping security teams share clear guidance right in PRs to speed reviews and reduce back-and-forth.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.