Manage Conversations in React Native

Learn how to launch, manage, and enrich Agentforce conversations in your React Native application.

Launch a Conversation 

There are two methods for opening the conversation UI:

launchConversation() 

Opens the conversation UI. If an existing conversation is available, it’s preserved and the user can continue where they left off.

1import { AgentforceService } from "@salesforce/react-native-agentforce";
2
3// Must configure first
4await AgentforceService.configure({
5  /* ... */
6});
7
8// Launch -- resumes existing conversation if available
9await AgentforceService.launchConversation();

This is the recommended method for most use cases. It avoids discarding conversation history and provides a smoother user experience.

startNewConversation() 

Closes any existing conversation and starts fresh. The previous conversation is terminated and a new one is created.

1// Force a fresh conversation
2await AgentforceService.startNewConversation();

Use this when you explicitly want to discard the previous conversation, for example, when the user switches accounts, resolves an issue, or navigates to a different context.

Preconditions 

Both methods require:

  1. The SDK must be configured via configure(). If not, the native module rejects with NOT_CONFIGURED.
  2. On Android, a current Activity must be available. If not, the promise rejects with ERROR: Activity not available.

Error Handling 

1try {
2  await AgentforceService.launchConversation();
3} catch (error) {
4  // error.code can be:
5  //   'NOT_CONFIGURED' -- configure() was not called
6  //   'LAUNCH_ERROR'   -- SDK failed to start session (iOS)
7  //   'ERROR'          -- general error (Android)
8  console.error("Launch failed:", error.message);
9}

Close a Conversation 

Terminate the current conversation and dismiss the conversation UI:

1const success = await AgentforceService.closeConversation();

The user can also close the conversation by:

  • iOS: Tapping the close button in the chat view’s top bar
  • Android: Tapping the back arrow in the toolbar

Conversation Lifecycle 

Understanding how conversations are managed helps you build better user experiences.

Conversation Reuse 

Calling launchConversation() multiple times reuses the same conversation object. This means:

  • The user sees their previous messages when re-opening the chat.
  • The agent retains context from the ongoing session.
  • Additional context set earlier is still active.

When Conversations are Cleared 

Conversations are cleared when:

  • closeConversation() is called
  • startNewConversation() is called
  • resetSettings() is called (clears everything)
  • Switching modes (for example, calling configure() with type: 'employee' after previously configuring type: 'service')
  • setEmployeeAgentId() is called with a different agent ID (iOS only)

Additional Context 

Additional context provides contextual information to the Agentforce agent during a conversation. This helps the agent deliver more personalized and relevant responses.

setAdditionalContext() must be called after launchConversation() or startNewConversation(). The context is set on the active conversation object, which doesn’t exist until a conversation is launched.

Note

Basic Usage 

1// Step 1: Launch conversation
2await AgentforceService.launchConversation();
3
4// Step 2: Set context
5await AgentforceService.setAdditionalContext({
6  variables: [
7    { name: "userId", type: "Text", value: "005xx0000001234" },
8    { name: "accountId", type: "Text", value: "001xx0000001234" },
9    { name: "priority", type: "Text", value: "high" },
10  ],
11});

Context Variable Types 

TypeDescriptionExample Value
TextString value'Jane Smith'
NumberNumeric value15234.56
BooleanTrue/falsetrue
DateISO date string'2024-01-15'
DateTimeISO datetime string'2026-03-11T10:30:00.000Z'
JsonJSON data (object or string){ language: 'en' }
ListArray value['ORD-001', 'ORD-002']
MoneyMonetary value50000
ObjectKey-value map{ street: '123 Main St', city: 'SF' }
RefReference value'003xx0000001234AAA'
VariableGeneric variable'sess_abc123'

Validation Rules 

The bridge validates context variables before sending them to the native SDK:

  • Type names are case-sensitive. Use 'Text' not 'text', 'Boolean' not 'boolean'. Invalid types cause an error.
  • Each variable must have a non-empty name and type. Missing fields cause an INVALID_CONTEXT error.
  • Validation errors are thrown synchronously before the native call, so you can catch them immediately.
  • The description field is only supported on Android. On iOS, it’s silently ignored.

Complete Example with All Types 

This example demonstrates all 11 context variable types:

1await AgentforceService.setAdditionalContext({
2  variables: [
3    // Text -- simple string value
4    {
5      name: "customerName",
6      type: "Text",
7      value: "Jane Smith",
8    },
9
10    // Number -- numeric value (double precision)
11    {
12      name: "accountBalance",
13      type: "Number",
14      value: 15234.56,
15    },
16
17    // Boolean -- true/false
18    {
19      name: "isVIPCustomer",
20      type: "Boolean",
21      value: true,
22    },
23
24    // Date -- ISO date string
25    {
26      name: "memberSince",
27      type: "Date",
28      value: "2024-01-15",
29    },
30
31    // DateTime -- ISO datetime string with timezone
32    {
33      name: "lastInteraction",
34      type: "DateTime",
35      value: "2026-03-11T10:30:00.000Z",
36    },
37
38    // Json -- JSON data (can be string or object)
39    {
40      name: "preferences",
41      type: "Json",
42      value: {
43        language: "en",
44        timezone: "America/Los_Angeles",
45        notifications: true,
46      },
47    },
48
49    // List -- array of values
50    {
51      name: "recentOrderIds",
52      type: "List",
53      value: ["ORD-2026-001", "ORD-2026-002", "ORD-2026-003"],
54    },
55
56    // Money -- monetary value
57    {
58      name: "creditLimit",
59      type: "Money",
60      value: 50000,
61    },
62
63    // Object -- key-value map
64    {
65      name: "shippingAddress",
66      type: "Object",
67      value: {
68        street: "123 Market Street",
69        city: "San Francisco",
70        state: "CA",
71        zip: "94105",
72        country: "US",
73      },
74    },
75
76    // Ref -- reference to another record
77    {
78      name: "primaryContactId",
79      type: "Ref",
80      value: "003xx0000001234AAA",
81    },
82
83    // Variable -- generic variable
84    {
85      name: "sessionToken",
86      type: "Variable",
87      value: "sess_abc123def456",
88    },
89
90    // With description (Android only, ignored on iOS)
91    {
92      name: "currentCaseId",
93      type: "Text",
94      value: "500xx0000009876AAA",
95      description: "The active support case for this customer",
96    },
97  ],
98});

The description field is only supported on Android. On iOS, it’s ignored.

Note

Hidden Prechat Fields 

Hidden prechat fields let you pass values to the Service Agent prechat form without displaying them to the user. Common use cases include pre-populating a ContactId, AccountId, or session token.

:::warning Android Limitation On Android, hidden prechat fields are stored but not sent to the native SDK during session initialization. This feature is fully functional on iOS only. If hidden prechat fields are critical to your use case, use iOS or wait for a future bridge update. :::

Hidden prechat fields only apply to Service Agent conversations. They have no effect for Employee Agent conversations.

Note

Usage 

Register hidden prechat fields before calling launchConversation():

1// Step 1: Register hidden prechat fields
2await AgentforceService.registerHiddenPreChatFields({
3  ContactId: "003xx0000001234AAA",
4  AccountId: "001xx0000005678AAA",
5  Subject: "Mobile App Support Request",
6});
7
8// Step 2: Launch conversation
9await AgentforceService.launchConversation();

Reading and Clearing Fields 

1// Read current fields
2const fields = await AgentforceService.getHiddenPreChatFields();
3console.log(fields); // { ContactId: '003xx...', AccountId: '001xx...' }
4
5// Clear all fields
6await AgentforceService.clearHiddenPreChatFields();

Complete Hidden Prechat Example 

This example shows the full flow of configuring, registering hidden fields, and launching:

1import React, { useState } from "react";
2import { View, Button, Text, Alert, StyleSheet } from "react-native";
3import { AgentforceService, HiddenPreChatFields } from "@salesforce/react-native-agentforce";
4
5export default function ServiceAgentWithPrechat() {
6  const [currentFields, setCurrentFields] = useState<HiddenPreChatFields>({});
7
8  const handleLaunchWithFields = async () => {
9    try {
10      // Step 1: Configure
11      await AgentforceService.configure({
12        type: "service",
13        serviceApiURL: "https://mycompany-support.my.salesforce-scrt.com",
14        organizationId: "00Dxx0000001234EAA",
15        esDeveloperName: "My_Service_Agent",
16      });
17
18      // Step 2: Register hidden fields (before launch)
19      await AgentforceService.registerHiddenPreChatFields({
20        ContactId: "003xx0000001234AAA",
21        AccountId: "001xx0000005678AAA",
22        Subject: "Mobile App Support",
23        Origin: "Mobile",
24        Priority: "High",
25      });
26
27      // Read back to verify
28      const fields = await AgentforceService.getHiddenPreChatFields();
29      setCurrentFields(fields);
30
31      // Step 3: Launch -- hidden fields are sent during session initialization
32      await AgentforceService.launchConversation();
33    } catch (error) {
34      Alert.alert("Error", String(error));
35    }
36  };
37
38  const handleClearFields = async () => {
39    await AgentforceService.clearHiddenPreChatFields();
40    setCurrentFields({});
41  };
42
43  return (
44    <View style={styles.container}>
45      <Text style={styles.title}>Hidden Prechat Fields</Text>
46
47      <View style={styles.fieldList}>
48        {Object.entries(currentFields).map(([key, value]) => (
49          <Text key={key} style={styles.field}>
50            {key}: {value}
51          </Text>
52        ))}
53        {Object.keys(currentFields).length === 0 && (
54          <Text style={styles.empty}>No fields registered</Text>
55        )}
56      </View>
57
58      <Button title="Launch with Fields" onPress={handleLaunchWithFields} />
59      <View style={styles.spacer} />
60      <Button title="Clear Fields" onPress={handleClearFields} color="red" />
61    </View>
62  );
63}
64
65const styles = StyleSheet.create({
66  container: { flex: 1, padding: 24 },
67  title: { fontSize: 20, fontWeight: "bold", marginBottom: 16 },
68  fieldList: { marginBottom: 24, padding: 12, backgroundColor: "#f5f5f5", borderRadius: 8 },
69  field: { fontSize: 14, marginBottom: 4, fontFamily: "monospace" },
70  empty: { color: "#999", fontStyle: "italic" },
71  spacer: { height: 12 },
72});

Platform Presentation Differences 

The conversation UI is presented differently on each platform.

iOS 

The conversation UI is presented as a full-screen modal:

  • Dismissal triggers onContainerClose, which calls dismiss(animated: true).
  • The SDK’s built-in top bar is shown.
  • The chat view is a SwiftUI view created by the SDK.

Android 

The conversation UI is launched as a separate Activity:

  • The user closes the conversation by tapping the back arrow.
  • It displays a Material 3 Scaffold with a Salesforce-blue top app bar.
  • AgentforceConversationActivity is a ComponentActivity that uses Jetpack Compose.
AspectiOSAndroid
PresentationFull-screen modalNew Activity
Top barSDK-providedCustom Material 3 TopAppBar
Close mechanismonContainerClose callbackBack arrow / system back
TransitionCover vertical animationStandard activity transition

See Also