Note: This release is in preview. Features described here don’t become generally available until the latest general availability date that Salesforce announces for this release. Before then, and where features are noted as beta, pilot, or developer preview, we can’t guarantee general availability within any particular time frame or at all. Make your purchase decisions only on the basis of generally available products and features.

Using Apex Services from Your Container

Use the lightning-container NPM module to call Apex methods from your Lightning container component.

To call Apex methods from lightning:container, you must set the CSP level to low in the manifest.json file. A CSP level of low allows the Lightning container component load resources from outside of the Lightning domain.

This is an Aura component that includes a Lightning container component that uses Apex services:
1<aura:component access="global" implements="flexipage:availableForAllPageTypes">
2
3    <aura:attribute access="private" name="error" type="String" default=""/>
4
5    <div>
6        <aura:if isTrue="{! !empty(v.error)}">
7            <lightning:textarea name="errorTextArea" value="{!v.error}" label="Error: "/>
8        </aura:if>
9
10        <lightning:container aura:id="ReactApp"
11                             src="/ApexController/index.html"
12                             onerror="{!c.handleError}"/>
13    </div>
14
15</aura:component>
This is the component’s controller:
1({
2    handleError: function(component, error, helper) {
3        var description = error.getParams().description;
4        component.set("v.error", description);
5    }
6})
There’s not a lot going on in the component’s JavaScript controller—the real action is in the JavaScript app, uploaded as a static resource, that the Lightning container references.
1import React, { Component } from 'react';
2import LCC from "lightning-container";
3import logo from './logo.svg';
4import './App.css';
5
6class App extends Component {
7
8  callApex() {
9    LCC.callApex("lcc1.ApexController.getAccount",
10                 this.state.name,
11                 this.handleAccountQueryResponse,
12                 {escape: true});
13  }
14
15  handleAccountQueryResponse(result, event) {
16    if (event.status) {
17      this.setState({account: result});
18    }
19    else if (event.type === "exception") {
20      console.log(event.message + " : " + event.where);
21    }
22  }
23
24  render() {
25    var account = this.state.account;
26
27    return (
28      <div className="App">
29        <div className="App-header">
30          <img src={logo} className="App-logo" alt="logo" />
31          <h2>Welcome to LCC</h2>
32        </div>
33        <p className="App-intro">
34          Account Name: <input type="text" id="accountName" value={this.state.name} onChange={e => this.onAccountNameChange(e)}/><br/>
35          <input type="submit" value="Call Apex Controller" onClick={this.callApex}/><br/>
36          Id: {account.Id}<br/>
37          Phone: {account.Phone}<br/>
38          Type: {account.Type}<br/>
39          Number of Employees: {account.NumberOfEmployees}<br/>
40        </p>
41      </div>
42    );
43  }
44
45  constructor(props) {
46    super(props);
47    this.state = {
48      name: "",
49      account: {}
50    };
51
52    this.handleAccountQueryResponse = this.handleAccountQueryResponse.bind(this);
53    this.onAccountNameChange = this.onAccountNameChange.bind(this);
54    this.callApex = this.callApex.bind(this);
55  }
56
57  onAccountNameChange(e) {
58    this.setState({name: e.target.value});
59  }
60}
61
62export default App;

The first function, callApex(), uses the LCC.callApex method to call getAccount, an Apex method that gets and displays an account’s information.