The Universal Adapter: Loading Any React App in Salesforce with a Single Component
AI Generated

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:

  • Package your React app as a resource
  • Create a specific Salesforce component to load that resource
  • Repeat this for every React app

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:

  1. First, it loads the core React libraries (React and ReactDOM)
  2. Then it finds and loads your specific React app
  3. Finally, it renders your React app in the right container, passing along any data it needs

The Key Functions That Make It Work:

Loading the Libraries and Your React App:

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

  1. Less Code: We deleted dozens of nearly identical components
  2. Faster Development: Adding a new React app takes minutes, not hours
  3. Easier Onboarding: New team members learn one pattern, not many
  4. Better Updates: When we need to improve how React works with Salesforce, we update one place
  5. Consistent Errors: All React loading issues are handled the same way

Making Your React Apps Work Well with This

For best results, your React apps should:

  • Have a clear entry point
  • Be properly bundled as Salesforce resources
  • Handle their own routing and state
  • Be ready to receive data through props

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.

Like
Reply

Great job Sonikaa Possimsetty, Love how clean and reusable the approach is

To view or add a comment, sign in

More articles by Sonikaa Possimsetty

Others also viewed

Explore content categories