I’m facing a challenge with rendering complex React Single Page Applications (SPAs) within the Salesforce interface. We’ve maximized what can be achieved with Lightning Web Components (LWC), but now we need to load complex React-based components that rely on data not stored in Salesforce.
The goal is to allow our engineering team to develop standalone React apps that can also run seamlessly within Salesforce. While the obvious solution is to use iframes, I’m exploring whether it’s possible to achieve this integration without relying on iframes.
What I’ve tried
1. Importing the React Bundle
I tried building the React app, uploading the bundle as a Static Resource, and loading it via LWC. Here’s what I attempted:
React App (main.tsx):
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
// Expose a global initialization function
window.initReactApp = function () {
createRoot(document.getElementById("salesforce-root-test")!).render(
<StrictMode>
<App />
</StrictMode>
);
};
LWC Component:
import { LightningElement } from 'lwc';
import { loadScript } from 'lightning/platformResourceLoader';
import myScript from '@salesforce/resourceUrl/my_js_file'; // React bundle
export default class MyComponent extends LightningElement {
connectedCallback() {
loadScript(this, myScript)
.then(() => {
console.log('Script loaded successfully');
this.initializeReactApp();
})
.catch((error) => {
console.error('Error loading script', error);
});
}
initializeReactApp() {
if (window.initReactApp) {
window.initReactApp();
} else {
console.error('React app initialization function not found');
}
}
}
However, even though the script loads successfully, window.initReactApp
remains undefined.
2. Using lightning:container
I explored using lightning:container
, as documented here. Unfortunately, it behaves like an iframe under the hood.
I uploaded a zip of my React app but encountered an issue with the following Aura component:
<aura:component>
<lightning:container src="{!$Resource.myApp + '/index.html'}" />
</aura:component>
Salesforce throws an error stating that it cannot find index.html
.
Question
Is there a way to render React SPAs within Salesforce without using iframes? Specifically, can I:
- Build and upload a React bundle as a Static Resource, then integrate it into a Salesforce component (e.g., LWC)?
- Use a better alternative than
lightning:container
for embedding React SPAs?
Or is this approach inherently flawed and impractical for Salesforce? Any guidance or proven techniques would be greatly appreciated!
Answer
To integrate a React SPA within Salesforce without using iframes, follow these steps:
Step 1: Modify the React App
Start by using the standard Vite React template. In the main.tsx
file, define a global initialization function that will render the React app within a provided DOM element:
function initReactApp(element: HTMLElement) {
createRoot(element).render(<App />);
}
Next, update the tsconfig.json
file to ensure compatibility with Salesforce’s LWC runtime. Change the target
property:
"target": "ES2020",
to:
"target": "ES5",
Step 2: Upload the React Bundle as a Static Resource
Build your React app and upload the resulting JavaScript bundle as a Static Resource in Salesforce.
Step 3: Create an LWC Component
In the LWC component, use the renderedCallback
lifecycle method to dynamically load the React bundle and initialize the app. Here’s the code for the LWC component:
import { LightningElement } from 'lwc';
import { loadScript } from 'lightning/platformResourceLoader';
import myApp from '@salesforce/resourceUrl/my_js_file';
export default class MyComponent extends LightningElement {
renderedCallback() {
loadScript(this, myApp)
.then(() => {
console.log('Script loaded successfully');
this.initializeReactApp();
})
.catch((error) => {
console.error('Error loading script', error);
});
}
initializeReactApp() {
if (window.initReactApp) {
const root = this.template.querySelector('.root');
console.log('root', root);
window.initReactApp(root);
} else {
console.error('React app initialization function not found');
}
}
}
Step 4: Define the Template
The LWC template should include a container div with the lwc:dom="manual"
directive, which allows dynamic DOM manipulation. Here’s an example template:
<template>
<div lwc:dom="manual" class="root"></div>
</template>
Final Outcome
Once deployed, the React SPA will render seamlessly within Salesforce inside the specified container in the LWC component. This approach avoids iframes and provides a more integrated user experience.
Enroll for Career-Building Salesforce Training with Real-Time Projects
Our Salesforce Course is thoughtfully designed to offer a deep understanding of the Salesforce platform, providing you with the essential skills required to thrive in the CRM industry. The curriculum includes key modules such as Salesforce Admin, Developer, and AI, seamlessly integrating theoretical learning with practical application. By participating in hands-on projects and real-world assignments, you’ll gain the expertise to solve complex business challenges confidently using Salesforce solutions. With guidance from experienced trainers, you’ll acquire both technical proficiency and industry insights to excel in the Salesforce ecosystem.
In addition to technical skills, our Salesforce training in Hyderabad provides personalized mentorship, certification preparation, and interview support to boost your career growth. You’ll receive extensive study materials, practical project exposure, and continuous guidance throughout the program. By the course’s conclusion, you’ll be ready for certification exams and equipped with problem-solving abilities that employers highly value. Begin your Salesforce career with us and explore limitless career opportunities.
Join our Free Demo today..!
Leave a Reply
You must be logged in to post a comment.