The Universal Adapter: Loading Any React App in Salesforce with a Single Component
The Problem We Solved
Our team faced a common challenge: we needed to use React apps inside Salesforce, but the process was clunky. Every time we created a new React micro frontend, we had to build a separate Lightning Web Component (LWC) just to load it. This meant writing nearly identical code over and over again.
Our Solution: One Component to Load Them All
We created a single, powerful LWC that can load any React application. This cut down our code significantly and made the development process much faster and cleaner.
What This Means (Even If You Don't Know Salesforce)
Think of it like this: Instead of creating a new adapter for each device you own, we built one universal adapter that works with everything.
Salesforce uses its own UI system called Lightning Web Components. When you want to use React (a popular JavaScript library) inside Salesforce, you typically need to:
Our solution eliminates this repetition.
How Our Generic Loader Works
The GenericReactLoader component is simple but powerful:
It Takes Three Inputs:
staticResourceName: The name of your React app
componentData: Any data to pass to your React app
debug: Turn debugging on/off
Loading Process in Plain English:
The Key Functions That Make It Work:
Loading the Libraries and Your React App:
Recommended by LinkedIn
async loadReactLibraries() {
try {
// Load React first
await loadScript(this, REACT);
this._React = this.getReactReference();
if (!this._React) {
throw new Error('React was loaded but cannot be accessed');
}
// Load ReactDOM
await loadScript(this, REACTDOM);
this._ReactDOM = this.getReactDOMReference();
if (!this._ReactDOM) {
throw new Error('ReactDOM was loaded but cannot be accessed');
}
// Dynamically load the specified React component
const resourceUrl = `/resource/${this.staticResourceName}`;
await loadScript(this, resourceUrl);
this.initializeReactComponent();
} catch (error) {
this.error = `Error loading React component: ${error.message}`;
console.error(this.error, error);
}
}
The Smart Part: Finding and Initializing Your React App:
initializeReactComponent() {
const container = this.template.querySelector('.react-container');
if (!container) {
this.error = 'React container not found';
return;
}
try {
// Try different ways to access the React component
const componentName = this.staticResourceName;
let reactComponent = window[componentName];
if (!reactComponent) {
// Try common naming patterns
const pascalCase = componentName.charAt(0).toUpperCase() + componentName.slice(1);
reactComponent = window[pascalCase];
}
if (!reactComponent) {
throw new Error(`React component '${componentName}' not found on window object`);
}
// Render the React component with data
if (typeof reactComponent.render === 'function') {
reactComponent.render(this._React, this._ReactDOM, container, this.componentData);
} else if (typeof reactComponent === 'function') {
// If it's a React component function
const element = this._React.createElement(reactComponent, this.componentData);
this._ReactDOM.render(element, container);
} else {
throw new Error('Invalid React component format');
}
} catch (error) {
this.error = `Error rendering React component: ${error.message}`;
console.error(this.error, error);
}
}
This flexibility means it works with most React apps without requiring special formatting. The component intelligently handles different ways React components might be structured and exposed.
Using the Component is Dead Simple
Instead of creating custom LWCs for each React app, you just do this:
<c-generic-react-loader
static-resource-name="myReactApp"
component-data={myData}>
</c-generic-react-loader>
That's it. One line replaces what used to be an entire component.
Real Benefits We've Seen
Making Your React Apps Work Well with This
For best results, your React apps should:
The Bottom Line
This solution bridges two powerful tools - Salesforce's LWC framework and React - with minimal fuss. It lets teams use React's flexibility inside Salesforce while keeping code clean and maintainable.
The result? Faster development, less frustration, and a cleaner codebase.
This approach shows how a little creative engineering can solve integration challenges without adding complexity. Sometimes the best solutions are the ones that remove code rather than add it.
#Salesforce #React #MicroFrontend #DeveloperProductivity #JavaScript
Hey Sonikaa Possimsetty This is insightful. Lets say if I need to integrate a react widget hosted in the private cloud. using microservices. can I leverage this process. any insights will help.
Great job Sonikaa Possimsetty, Love how clean and reusable the approach is