A Multi-Framework app lives in your Salesforce DX project as a UIBundle. The UIBundle represents your app’s UI and works with several other metadata types to define the app on the platform. In your project, its source code, build configuration, and metadata definition are stored together in a self-contained folder. When you deploy it, this metadata creates a UIBundle record that establishes the app’s identity on the Salesforce Platform and declares which containers can host it.
This topic describes the files and metadata that make up an app, whichever framework you use.
UIBundle Files
The Salesforce DX project structure includes a force-app/main/default folder that contains a uiBundles folder. Application metadata and content live together in this uiBundles directory. Each application subdirectory is a complete, self-contained unit with its own metadata definition (.uibundle-meta.xml), runtime configuration (ui-bundle.json), source code, and compiled assets.
The .uibundle-meta.xml file, located in the force-app/main/default/uiBundles/{app_name} folder, defines the metadata for the app’s UI.
The target property in this file declares which kind of Salesforce container can use this UIBundle for its UI. It doesn’t surface anything on its own. Instead, a CustomApplication or a site references the UIBundle, and that container is what appears in the Salesforce UI.
CustomApplication lets a CustomApplication, which is an internal, employee-facing app, use the UIBundle. This is the default target if you don’t specify a value. The CustomApplication appears in the App Launcher and opens in Salesforce, rendering its UI from the UIBundle.
Experience lets an Experience Cloud site use the UIBundle. The site appears in the Digital Experiences app and in the App Launcher, where selecting it opens the site URL in a new tab, and renders its UI from the UIBundle.
In both cases, additional metadata types are required to integrate your app with the Salesforce Platform and make it available in the UI. For example, to make an internal app available in the App Launcher, you also need a CustomApplication metadata type that references the UIBundle. See Internal and External App Files.
Important
Here’s an example of the UI bundle metadata that’s deployed with an internal user app.
The isActive flag controls whether the deployed bundle is served, and version is a schema-version integer that starts at 1.
The ui-bundle.json File
The ui-bundle.json file, located in the force-app/main/default/uiBundles/{app_name} folder, is the app’s runtime configuration file. The file can include these properties.
Property
Type
Description
outputDir
string
Required. The relative path to the directory that contains built application assets. The default value is “dist” for bundled apps.
apiVersion
string
The Salesforce API version. Uses the format “vXX.X”; for example, “v66.0”. Be sure to use the same API version as the Salesforce org where you’re deploying your app. Defaults to the current org version.
routing
string
Block containing custom URL handling. If omitted, standard file-based serving is used.
routing.fileBasedRouting
boolean
When true, URLs are automatically mapped to the folder structure in outputDir. Defaults to true.
routing.trailingSlash
string
Controls how the platform handles trailing slashes in URLs. Valid values are: • never: Removes the slash (for example, redirects “/page/” to “/page”). • always: Adds a slash (for example, redirects “/page” to “/page/”). • auto: No change.
routing.fallback
string
Specifies the file to serve when a request doesn’t match any static asset or explicit rule. Set to index.html to allow client-side routing for single-page apps (SPAs).
routing.rewrites
array
An array of rewrite rules that serve a different file without changing the browser URL.
routing.rewrites.route
string
Required for rewrites. The source URL pattern. Supports named parameters (:id) and wildcards (*).
routing.rewrites.target
string
Required for rewrites. The internal file path to serve.
routing.redirects
array
An array of redirect rules that return an HTTP redirect response to the client. Rules are evaluated in order.
routing.redirects.route
string
Required for redirects. The source URL pattern. Supports named parameters (:id) and wildcards (*).
routing.redirects.target
string
Required for redirects. The destination URL.
routing.redirects.statusCode
string
Required for redirects. The HTTP status for the redirect: • 301: Moved permanently (cacheable) • 302: Found (temporary, not cached) • 307: Temporary redirect (preserves request method, not cached) • 308: Permanent redirect (preserves request method, cacheable)
This example shows all possible configuration options for a ui-bundle.json file.
This example shows a typical configuration file for a single-page app, which ensures that the app works correctly when a user refreshes the page on a sub-route (for example, /dashboard).
When you create an app, you choose an internal or an external template, which provides the necessary UIBundle project structure along with the related metadata that differs by use case. The template names differ by framework—for example, reactinternalapp and reactexternalapp for React, or angularinternalapp and angularexternalapp for Angular. For the full list of templates and the generate commands, see Generate an App from a Template.
Internal App Files
Use an internal template to create internal-facing apps for employees signing in with their Salesforce credentials.
Projects based on an internal template also require the CustomApplication metadata. This type defines and configures a Salesforce app, and connects your app to the App Launcher. The force-app/main/default/applications folder contains the .app-meta.xml file, which includes a field called uiBundle. This field contains the fully qualified name of the UIBundle that represents your app, such as c__myapp.
When a CustomApplication references the UIBundle through its uiBundle field, and the UIBundle’s target is set to CustomApplication in the .uibundle-meta.xml file, the CustomApplication appears in the App Launcher and renders its UI from the UIBundle.
Similar to a standard Salesforce app, you can control user access to the app using profiles and permission sets. The internal templates also generate an <AppName> Access permission set that grants app visibility and the API Enabled permission. For more information, see Manage Your App and Grant User Access.
Note
External App Files
Use an external template to create external-facing apps for business-to-business (B2B) and business-to-consumer (B2C) use cases, such as partners or customers signing in from outside your org. The template provides a prebuilt shell that includes an Experience Cloud site with several pages, navigation, and authentication.
Projects based on an external template also require several additional metadata types to support the Experience Cloud site. The files are contained in these folders in force-app/main/default:
digitalExperienceConfigs: The DigitalExperienceConfig metadata type represents the configuration details for your org’s workspaces, such as the site label, site URL path prefix, and workspace type.
digitalExperiences: The DigitalExperience metadata type represents a collection of related content items that form the site when combined with data from the DigitalExperienceConfig metadata type.
networks: The Network metadata type represents an Experience Cloud site.
sites: The CustomSite metadata type represents a Salesforce site.
Unlike a standard LWR site, the digitalExperiences folder contains only the sfdc_cms_site folder. In the content.json file in the folder:
The appContainer property is set to true to indicate that the site is used in a Multi-Framework app.
The appSpace property refers to the related app. Make sure that the value uses the format NamespacePrefix__DeveloperName (for example, MyNamespace__MyWebApp or c__MyWebApp for orgs without a registered namespace).