> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.qonversion.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Displaying No-Codes

> First, you need to initialize the SDK. To do this, use the same project key that you use to initialize the Qonversion SDK.

<CodeGroup>
  ```swift Swift theme={null}
  // You can initialize using only project key
  let configuration = NoCodesConfiguration(projectKey: "projectKey")
  NoCodes.initialize(with: configuration)
  ```

  ```kotlin Kotlin theme={null}
  // You can initialize using only project key
  val noCodesConfig = NoCodesConfig.Builder(this, "projectKey").build()
  NoCodes.initialize(noCodesConfig)
  ```

  ```java Java theme={null}
  // You can initialize using only project key
  final NoCodesConfig noCodesConfig = new NoCodesConfig.Builder(this, "projectKey").build();
  NoCodes.initialize(noCodesConfig);
  ```

  ```typescript React Native theme={null}
  // You can initialize using only project key
  const noCodesConfig = new NoCodesConfigBuilder('projectKey')
    .build();
  NoCodes.initialize(noCodesConfig);
  ```

  ```dart Flutter theme={null}
  // You can initialize using only project key
  final noCodesConfig = new NoCodesConfigBuilder(projectKey).build();
  NoCodes.initialize(noCodesConfig);
  ```

  ```csharp Unity theme={null}
  // You can initialize using only project key
  var noCodesConfig = new NoCodesConfigBuilder("projectKey")
      .Build();
  NoCodes.Initialize(noCodesConfig);
  ```

  ```typescript Cordova theme={null}
  // You can initialize using only project key
  const noCodesConfig = new Qonversion.NoCodesConfigBuilder('projectKey')
    .build();
  Qonversion.NoCodes.initialize(noCodesConfig);
  ```

  ```typescript Capacitor theme={null}
  // You can initialize using only project key
  const noCodesConfig = new NoCodesConfigBuilder('projectKey')
    .build();
  NoCodes.initialize(noCodesConfig);
  ```
</CodeGroup>

Then you can set the delegates for handling events and customizing screens as follows - *(optional)*:

<CodeGroup>
  ```swift Swift theme={null}
  // The first delegate is used for main events (e.g., screen opened, button tapped).
  NoCodes.shared.set(delegate: self)
  // The second is for screen customization (if you want to override default styles).
  NoCodes.shared.set(screenCustomizationDelegate: self)

  // Delegates can be also passed via the initialization through the configuration:
  let noCodesConfig = NoCodesConfiguration(projectKey: "projectKey", delegate: self, screenCustomizationDelegate: self)
  ```

  ```kotlin Kotlin theme={null}
  // The first delegate is used for main events (e.g., screen opened, button tapped).
  NoCodes.shared.setDelegate(this)
  // The second is for screen customization (if you want to override default styles).
  NoCodes.shared.setScreenCustomizationDelegate(this)

  // Delegates can be also passed via the initialization through the configuration:
  val noCodesConfig = NoCodesConfig.Builder(this, "projectKey")
    .setDelegate(this)
    .setScreenCustomizationDelegate(this)
    .build()
  ```

  ```java Java theme={null}
  // The first delegate is used for main events (e.g., screen opened, button tapped).
  NoCodes.getSharedInstance().setDelegate(this);
  // The second is for screen customization (if you want to override default styles).
  NoCodes.getSharedInstance().setScreenCustomizationDelegate(this);

  // Delegates can be also passed via the initialization through the configuration:
  final NoCodesConfig noCodesConfig = new NoCodesConfig.Builder(this, "projectKey")
    .setDelegate(this)
    .setScreenCustomizationDelegate(this)
    .build();
  ```

  ```typescript React Native theme={null}
  // Set the listener via the initialization through the configuration
  // It is used for main events (e.g., screen opened, button tapped).
  const noCodesConfig = new NoCodesConfigBuilder('projectKey')
    .setNoCodesListener(this)
  .build();

  // Set presentation style config before showing screen if needed
  const screenConfig = new ScreenPresentationConfig(ScreenPresentationStyle.FULL_SCREEN, true);
  NoCodes.getSharedInstance().setScreenPresentationConfig(screenConfig, 'yourContextKey');
  ```

  ```dart Flutter theme={null}
  // Set presentation style config before showing screen if needed
  final config = NoCodesPresentationConfig(
      animated: true,
      presentationStyle: NoCodesPresentationStyle.fullScreen,
  );

  NoCodes.getSharedInstance().setScreenPresentationConfig(config, contextKey: 'yourContextKey');

  // Subscribe to separate NoCodes event streams
  _screenShownStream = NoCodes.getSharedInstance().screenShownStream.listen((event) {
      // add functionality here
  });

  _finishedStream = NoCodes.getSharedInstance().finishedStream.listen((event) {
      // add functionality here
  });

  _actionStartedStream = NoCodes.getSharedInstance().actionStartedStream.listen((event) {
      // add functionality here
  });

  _actionFailedStream = NoCodes.getSharedInstance().actionFailedStream.listen((event) {
      // add functionality here
  });

  _actionFinishedStream = NoCodes.getSharedInstance().actionFinishedStream.listen((event) {
      // add functionality here
  });

  _screenFailedToLoadStream = NoCodes.getSharedInstance().screenFailedToLoadStream.listen((event) {
      // add functionality here
  });
  ```

  ```csharp Unity theme={null}
  // Set the delegate via the initialization through the configuration
  // It is used for main events (e.g., screen opened, button tapped).
  var noCodesConfig = new NoCodesConfigBuilder("projectKey")
      .SetNoCodesDelegate(this)
      .Build();
  NoCodes.Initialize(noCodesConfig);

  // Set presentation style config before showing screen if needed
  var screenConfig = new ScreenPresentationConfig(ScreenPresentationStyle.FullScreen, true);
  NoCodes.GetSharedInstance().SetScreenPresentationConfig(screenConfig, "yourContextKey");
  ```

  ```typescript Cordova theme={null}
  // Set the listener via the initialization through the configuration
  // It is used for main events (e.g., screen opened, button tapped).
  const noCodesConfig = new Qonversion.NoCodesConfigBuilder('projectKey')
    .setNoCodesListener(this)
  .build();

  // Set presentation style config before showing screen if needed
  const screenConfig = new Qonversion.ScreenPresentationConfig(Qonversion.ScreenPresentationStyle.FULL_SCREEN, true);
  Qonversion.NoCodes.getSharedInstance().setScreenPresentationConfig(screenConfig, 'yourContextKey');
  ```

  ```typescript Capacitor theme={null}
  // Set the listener via the initialization through the configuration
  // It is used for main events (e.g., screen opened, button tapped).
  const noCodesConfig = new NoCodesConfigBuilder('projectKey')
    .setNoCodesListener(this)
  .build();

  // Set presentation style config before showing screen if needed
  const screenConfig = new ScreenPresentationConfig(ScreenPresentationStyle.FULL_SCREEN, true);
  NoCodes.getSharedInstance().setScreenPresentationConfig(screenConfig, 'yourContextKey');
  ```
</CodeGroup>

After initializing the SDK, you can move forward and display the No-Codes screen:

<CodeGroup>
  ```swift Swift theme={null}
  NoCodes.shared.showScreen(withContextKey: "yourContextKey")
  ```

  ```kotlin Kotlin theme={null}
  NoCodes.shared.showScreen("yourContextKey")
  ```

  ```java Java theme={null}
  NoCodes.getSharedInstance().showScreen("yourContextKey");
  ```

  ```typescript React Native theme={null}
  NoCodes.getSharedInstance().showScreen('yourContextKey');
  ```

  ```dart Flutter theme={null}
  NoCodes.getSharedInstance().showScreen('yourContextKey');
  ```

  ```csharp Unity theme={null}
  NoCodes.GetSharedInstance().ShowScreen("yourContextKey");
  ```

  ```typescript Cordova theme={null}
  Qonversion.NoCodes.getSharedInstance().showScreen('yourContextKey');
  ```

  ```typescript Capacitor theme={null}
  NoCodes.getSharedInstance().showScreen('yourContextKey');
  ```
</CodeGroup>

<Info>
  If you want to use Qonversion No-Codes with your own purchase infrastructure, [see](using-no-codes-with-custom-purchases-handling) how you can do it in two simple steps.
</Info>

## Passing custom variables

You can pass dynamic values from your app into a No-Code screen and reference them in conditional logic, dynamic text, or component visibility rules. Variables are scoped to a specific `contextKey`, so different screens can receive different values, and each value is queried at the moment a screen is about to be shown — including sub-screens reached via in-screen navigation.

For native SDKs, implement a delegate that returns a `Map`/dictionary keyed by `contextKey`. For cross-platform SDKs, pass the values directly to `showScreen`.

<CodeGroup>
  ```swift Swift theme={null}
  // 1. Implement NoCodesCustomVariablesDelegate
  extension MyClass: NoCodesCustomVariablesDelegate {
    func customVariables(for contextKey: String) -> [String: String] {
      return ["button_color": "red", "username": "Alex"]
    }
  }

  // 2. Provide it to the SDK
  NoCodes.shared.set(customVariablesDelegate: self)
  // Or via configuration:
  let configuration = NoCodesConfiguration(projectKey: "projectKey", customVariablesDelegate: self)
  ```

  ```kotlin Kotlin theme={null}
  // 1. Implement CustomVariablesDelegate
  class MyActivity : AppCompatActivity(), CustomVariablesDelegate {
    override fun getCustomVariables(contextKey: String): Map<String, String> {
      return mapOf("button_color" to "red", "username" to "Alex")
    }
  }

  // 2. Provide it to the SDK
  NoCodes.shared.setCustomVariablesDelegate(this)
  // Or via configuration:
  val noCodesConfig = NoCodesConfig.Builder(this, "projectKey")
    .setCustomVariablesDelegate(this)
    .build()
  ```

  ```java Java theme={null}
  // 1. Implement CustomVariablesDelegate
  public class MyActivity extends AppCompatActivity implements CustomVariablesDelegate {
    @NonNull
    @Override
    public Map<String, String> getCustomVariables(@NonNull String contextKey) {
      Map<String, String> variables = new HashMap<>();
      variables.put("button_color", "red");
      variables.put("username", "Alex");
      return variables;
    }
  }

  // 2. Provide it to the SDK
  NoCodes.getSharedInstance().setCustomVariablesDelegate(this);
  // Or via configuration:
  final NoCodesConfig noCodesConfig = new NoCodesConfig.Builder(this, "projectKey")
    .setCustomVariablesDelegate(this)
    .build();
  ```

  ```typescript React Native theme={null}
  const customVariables = { button_color: 'red', username: 'Alex' };
  NoCodes.getSharedInstance().showScreen('yourContextKey', customVariables);
  ```

  ```dart Flutter theme={null}
  final customVariables = {'button_color': 'red', 'username': 'Alex'};
  NoCodes.getSharedInstance().showScreen('yourContextKey', customVariables: customVariables);
  ```

  ```csharp Unity theme={null}
  var customVariables = new Dictionary<string, string> {
    { "button_color", "red" },
    { "username", "Alex" }
  };
  NoCodes.GetSharedInstance().ShowScreen("yourContextKey", customVariables);
  ```

  ```typescript Cordova theme={null}
  const customVariables = { button_color: 'red', username: 'Alex' };
  Qonversion.NoCodes.getSharedInstance().showScreen('yourContextKey', customVariables);
  ```

  ```typescript Capacitor theme={null}
  const customVariables = { button_color: 'red', username: 'Alex' };
  NoCodes.getSharedInstance().showScreen('yourContextKey', customVariables);
  ```
</CodeGroup>

<Info>
  Values must be strings. Inside the screen, variables are injected into the JavaScript context via `window.noCodesSetVariable(name, value)` and then become available in conditional logic, dynamic text bindings, and visibility rules.
</Info>

## Delegates

Earlier, we discussed how to set delegates. Now, let's explore their purpose.

### Main delegate

The main delegate is needed so that you can receive messages about what is happening during the execution of No-Codes, as well as to provide us with the screen from which to start navigation and display the No-Codes screen. Let's go through this step by step.

<Warning>
  ### Unity Warning

  Unity NoCodes delegate events are delivered on iOS only. On Android, the No-Codes screen runs as a separate Activity on top of Unity's Activity and Unity's game loop is paused while the screen is shown, so delegate events do not fire.
</Warning>

##### controllerForNavigation *(iOS only)*

<CodeGroup>
  ```swift Swift theme={null}
  func controllerForNavigation() -> UIViewController?
  ```
</CodeGroup>

In this function, you must return a UIViewController from which we will start displaying the No-Codes flow. If you do not provide one, we will take the topmost screen in the current stack.

##### Screen shown event

<CodeGroup>
  ```swift Swift theme={null}
  func noCodesHasShownScreen(id: String)
  ```

  ```kotlin Kotlin theme={null}
  fun onScreenShown(screenId: String)
  ```

  ```java Java theme={null}
  void onScreenShown(String screenId)
  ```

  ```typescript React-Native theme={null}
  onScreenShown: (id: string) => {}
  ```

  ```dart Flutter theme={null}
  _screenShownStream = NoCodes.getSharedInstance().screenShownStream.listen((event) {
      // add functionality here
  });
  ```

  ```csharp Unity theme={null}
  void OnScreenShown(string contextKey)
  ```

  ```typescript Cordova theme={null}
  onScreenShown: (id: string) => {}
  ```

  ```typescript Capacitor theme={null}
  onScreenShown: (id: string) => {}
  ```
</CodeGroup>

This function notifies about the display of a screen with a specific identifier

#### Action execution start event

<CodeGroup>
  ```swift Swift theme={null}
  func noCodesStartsExecuting(action: NoCodesAction)
  ```

  ```kotlin Kotlin theme={null}
  fun onActionStartedExecuting(action: QAction)
  ```

  ```java Java theme={null}
  void onActionStartedExecuting(QAction action)
  ```

  ```typescript React-Native theme={null}
  onActionStartedExecuting: (action: NoCodesAction) => {}
  ```

  ```dart Flutter theme={null}
  _actionStartedStream = NoCodes.getSharedInstance().actionStartedStream.listen((event) {
      // add functionality here
  });
  ```

  ```csharp Unity theme={null}
  void OnActionStarted(NoCodesAction action)
  ```

  ```typescript Cordova theme={null}
  onActionStartedExecuting: (action: Qonversion.NoCodesAction) => {}
  ```

  ```typescript Capacitor theme={null}
  onActionStartedExecuting: (action: NoCodesAction) => {}
  ```
</CodeGroup>

This function notifies you that executing the action you set up through our dashboard has begun.

#### Action execution fail event

<CodeGroup>
  ```swift Swift theme={null}
  func noCodesFailedToExecute(action: NoCodesAction, error: Error?)
  ```

  ```kotlin Kotlin theme={null}
  fun onActionFailedToExecute(action: QAction) {
    // For details look at the `error` property of the action
  }
  ```

  ```java Java theme={null}
  void onActionFailedToExecute(QAction action) {
    // For details look at the `error` property of the action
  }
  ```

  ```typescript React-Native theme={null}
  onActionFailedToExecute: (action: NoCodesAction) => {}
  ```

  ```dart Flutter theme={null}
  _actionFailedStream = NoCodes.getSharedInstance().actionFailedStream.listen((event) {
      // add functionality here
  });
  ```

  ```csharp Unity theme={null}
  void OnActionFailed(NoCodesAction action)
  ```

  ```typescript Cordova theme={null}
  onActionFailedToExecute: (action: Qonversion.NoCodesAction) => {}
  ```

  ```typescript Capacitor theme={null}
  onActionFailedToExecute: (action: NoCodesAction) => {}
  ```
</CodeGroup>

This function notifies you that executing the action you set up through our dashboard has failed.

#### Action execution finish event

<CodeGroup>
  ```swift Swift theme={null}
  func noCodesFinishedExecuting(action: NoCodesAction)
  ```

  ```kotlin Kotlin theme={null}
  fun onActionFinishedExecuting(action: QAction)
  ```

  ```java Java theme={null}
  void onActionFinishedExecuting(QAction action)
  ```

  ```typescript React-Native theme={null}
  onActionFinishedExecuting: (action: NoCodesAction) => {}
  ```

  ```dart Flutter theme={null}
  _actionFinishedStream = NoCodes.getSharedInstance().actionFinishedStream.listen((event) {
      // add functionality here
  });
  ```

  ```csharp Unity theme={null}
  void OnActionFinished(NoCodesAction action)
  ```

  ```typescript Cordova theme={null}
  onActionFinishedExecuting: (action: Qonversion.NoCodesAction) => {}
  ```

  ```typescript Capacitor theme={null}
  onActionFinishedExecuting: (action: NoCodesAction) => {}
  ```
</CodeGroup>

This function notifies you that the action you set up through our dashboard has been executed.

#### Screen finished event

<CodeGroup>
  ```swift Swift theme={null}
  func noCodesFinished()
  ```

  ```kotlin Kotlin theme={null}
  fun onFinished()
  ```

  ```java Java theme={null}
  void onFinished()
  ```

  ```typescript React-Native theme={null}
  onFinished: () => {}
  ```

  ```dart Flutter theme={null}
  _finishedStream = NoCodes.getSharedInstance().finishedStream.listen((event) {
      // add functionality here
  });
  ```

  ```csharp Unity theme={null}
  void OnFinished()
  ```

  ```typescript Cordova theme={null}
  onFinished: () => {}
  ```

  ```typescript Capacitor theme={null}
  onFinished: () => {}
  ```
</CodeGroup>

This function notifies that the No-Codes flow has been completed and No-Codes has been finished.

#### Screen loading failed

<CodeGroup>
  ```swift Swift theme={null}
  func noCodesFailedToLoadScreen(error: Error?)
  ```

  ```kotlin Kotlin theme={null}
  fun onScreenFailedToLoad(error: NoCodesError)
  ```

  ```java Java theme={null}
  void onScreenFailedToLoad(NoCodesError error)
  ```

  ```typescript React-Native theme={null}
  onScreenFailedToLoad: (error: NoCodesError) => {}
  ```

  ```dart Flutter theme={null}
  _screenFailedToLoadStream = NoCodes.getSharedInstance().screenFailedToLoadStream.listen((event) {
      // add functionality here
  });
  ```

  ```csharp Unity theme={null}
  void OnScreenFailedToLoad(NoCodesError error)
  ```

  ```typescript Cordova theme={null}
  onScreenFailedToLoad: (error: Qonversion.NoCodesError) => {}
  ```

  ```typescript Capacitor theme={null}
  onScreenFailedToLoad: (error: NoCodesError) => {}
  ```
</CodeGroup>

This function is called when No-Codes screen loading has failed.

### Localization

By default, No-Code screens automatically detect the device's system language and display the appropriate localization if available. You can override this behavior by setting a custom locale, which takes priority over the automatic system language detection.

The locale should be in standard format (e.g., `"en"`, `"en-US"`, `"de"`, `"de-DE"`). Pass `nil`/`null` to reset to the system default locale.

**Setting locale during initialization:**

<CodeGroup>
  ```swift Swift theme={null}
  var config = NoCodesConfiguration(
      projectKey: "your_project_key",
      locale: "de-DE"
  )
  NoCodes.initialize(with: config)
  ```

  ```kotlin Kotlin theme={null}
  val config = NoCodesConfig.Builder(context, "your_project_key")
      .setLocale("de-DE")
      .build()
  NoCodes.initialize(config)
  ```

  ```java Java theme={null}
  NoCodesConfig config = new NoCodesConfig.Builder(context, "your_project_key")
      .setLocale("de-DE")
      .build();
  NoCodes.initialize(config);
  ```

  ```typescript React Native theme={null}
  const noCodesConfig = new NoCodesConfigBuilder("projectKey")
      .setLocale("de-DE")
      .build();
  NoCodes.initialize(noCodesConfig);
  ```

  ```dart Flutter theme={null}
  final noCodesConfig = NoCodesConfigBuilder("projectKey")
      .setLocale("de-DE")
      .build();
  NoCodes.initialize(noCodesConfig);
  ```

  ```csharp Unity theme={null}
  var noCodesConfig = new NoCodesConfigBuilder("projectKey")
      .SetLocale("de-DE")
      .Build();
  NoCodes.Initialize(noCodesConfig);
  ```

  ```typescript Cordova theme={null}
  const noCodesConfig = new Qonversion.NoCodesConfigBuilder("projectKey")
      .setLocale("de-DE")
      .build();
  Qonversion.NoCodes.initialize(noCodesConfig);
  ```

  ```typescript Capacitor theme={null}
  const noCodesConfig = new NoCodesConfigBuilder("projectKey")
      .setLocale("de-DE")
      .build();
  NoCodes.initialize(noCodesConfig);
  ```
</CodeGroup>

**Setting locale after initialization:**

<CodeGroup>
  ```swift Swift theme={null}
  NoCodes.shared.setLocale("fr-FR")
  NoCodes.shared.showScreen(withContextKey: "your_context_key")

  // Reset to system default
  NoCodes.shared.setLocale(nil)
  ```

  ```kotlin Kotlin theme={null}
  NoCodes.shared.setLocale("fr-FR")
  NoCodes.shared.showScreen("your_context_key")

  // Reset to system default
  NoCodes.shared.setLocale(null)
  ```

  ```java Java theme={null}
  NoCodes.getSharedInstance().setLocale("fr-FR");
  NoCodes.getSharedInstance().showScreen("your_context_key");

  // Reset to system default
  NoCodes.getSharedInstance().setLocale(null);
  ```

  ```typescript React Native theme={null}
  NoCodes.getSharedInstance().setLocale("fr-FR");
  NoCodes.getSharedInstance().showScreen("yourContextKey");

  // Reset to system default
  NoCodes.getSharedInstance().setLocale(null);
  ```

  ```dart Flutter theme={null}
  NoCodes.getSharedInstance().setLocale("fr-FR");
  NoCodes.getSharedInstance().showScreen("yourContextKey");

  // Reset to system default
  NoCodes.getSharedInstance().setLocale(null);
  ```

  ```csharp Unity theme={null}
  NoCodes.GetSharedInstance().SetLocale("fr-FR");
  NoCodes.GetSharedInstance().ShowScreen("yourContextKey");

  // Reset to system default
  NoCodes.GetSharedInstance().SetLocale(null);
  ```

  ```typescript Cordova theme={null}
  Qonversion.NoCodes.getSharedInstance().setLocale("fr-FR");
  Qonversion.NoCodes.getSharedInstance().showScreen("yourContextKey");

  // Reset to system default
  Qonversion.NoCodes.getSharedInstance().setLocale(null);
  ```

  ```typescript Capacitor theme={null}
  NoCodes.getSharedInstance().setLocale("fr-FR");
  NoCodes.getSharedInstance().showScreen("yourContextKey");

  // Reset to system default
  NoCodes.getSharedInstance().setLocale(null);
  ```
</CodeGroup>

### Theme

No-Code screens support light and dark themes. By default, screens automatically adapt to the device's system appearance (Auto mode). You can override this behavior by setting a specific theme, which takes priority over the automatic system theme detection.

<Warning>
  Currently, the theme only affects skeleton loader colors, with full theming support for the No-Code Builder coming soon
</Warning>

Available theme modes:

* **Auto** (default) - Follows the device's system appearance
* **Light** - Forces light theme regardless of device settings
* **Dark** - Forces dark theme regardless of device settings

**Setting theme during initialization:**

<CodeGroup>
  ```swift Swift theme={null}
  var config = NoCodesConfiguration(
      projectKey: "your_project_key",
      theme: .dark
  )
  NoCodes.initialize(with: config)
  ```

  ```kotlin Kotlin theme={null}
  val config = NoCodesConfig.Builder(context, "your_project_key")
      .setTheme(NoCodesTheme.Dark)
      .build()
  NoCodes.initialize(config)
  ```

  ```java Java theme={null}
  NoCodesConfig config = new NoCodesConfig.Builder(context, "your_project_key")
      .setTheme(NoCodesTheme.Dark)
      .build();
  NoCodes.initialize(config);
  ```

  ```typescript React Native theme={null}
  const noCodesConfig = new NoCodesConfigBuilder("projectKey")
      .setTheme(NoCodesTheme.DARK)
      .build();
  NoCodes.initialize(noCodesConfig);
  ```

  ```dart Flutter theme={null}
  final noCodesConfig = NoCodesConfigBuilder("projectKey")
      .setTheme(NoCodesTheme.dark)
      .build();
  NoCodes.initialize(noCodesConfig);
  ```

  ```csharp Unity theme={null}
  var noCodesConfig = new NoCodesConfigBuilder("projectKey")
      .SetTheme(NoCodesTheme.Dark)
      .Build();
  NoCodes.Initialize(noCodesConfig);
  ```

  ```typescript Cordova theme={null}
  const noCodesConfig = new Qonversion.NoCodesConfigBuilder("projectKey")
      .setTheme(Qonversion.NoCodesTheme.DARK)
      .build();
  Qonversion.NoCodes.initialize(noCodesConfig);
  ```

  ```typescript Capacitor theme={null}
  const noCodesConfig = new NoCodesConfigBuilder("projectKey")
      .setTheme(NoCodesTheme.DARK)
      .build();
  NoCodes.initialize(noCodesConfig);
  ```
</CodeGroup>

**Setting theme after initialization:**

<CodeGroup>
  ```swift Swift theme={null}
  NoCodes.shared.setTheme(.light)
  NoCodes.shared.showScreen(withContextKey: "your_context_key")

  // Reset to auto (follow system appearance)
  NoCodes.shared.setTheme(.auto)
  ```

  ```kotlin Kotlin theme={null}
  NoCodes.shared.setTheme(NoCodesTheme.Light)
  NoCodes.shared.showScreen("your_context_key")

  // Reset to auto (follow system appearance)
  NoCodes.shared.setTheme(NoCodesTheme.Auto)
  ```

  ```java Java theme={null}
  NoCodes.getSharedInstance().setTheme(NoCodesTheme.Light);
  NoCodes.getSharedInstance().showScreen("your_context_key");

  // Reset to auto (follow system appearance)
  NoCodes.getSharedInstance().setTheme(NoCodesTheme.Auto);
  ```

  ```typescript React Native theme={null}
  NoCodes.getSharedInstance().setTheme(NoCodesTheme.LIGHT);
  NoCodes.getSharedInstance().showScreen("yourContextKey");

  // Reset to auto (follow system appearance)
  NoCodes.getSharedInstance().setTheme(NoCodesTheme.AUTO);
  ```

  ```dart Flutter theme={null}
  NoCodes.getSharedInstance().setTheme(NoCodesTheme.light);
  NoCodes.getSharedInstance().showScreen("yourContextKey");

  // Reset to auto (follow system appearance)
  NoCodes.getSharedInstance().setTheme(NoCodesTheme.auto);
  ```

  ```csharp Unity theme={null}
  NoCodes.GetSharedInstance().SetTheme(NoCodesTheme.Light);
  NoCodes.GetSharedInstance().ShowScreen("yourContextKey");

  // Reset to auto (follow system appearance)
  NoCodes.GetSharedInstance().SetTheme(NoCodesTheme.Auto);
  ```

  ```typescript Cordova theme={null}
  Qonversion.NoCodes.getSharedInstance().setTheme(Qonversion.NoCodesTheme.LIGHT);
  Qonversion.NoCodes.getSharedInstance().showScreen("yourContextKey");

  // Reset to auto (follow system appearance)
  Qonversion.NoCodes.getSharedInstance().setTheme(Qonversion.NoCodesTheme.AUTO);
  ```

  ```typescript Capacitor theme={null}
  NoCodes.getSharedInstance().setTheme(NoCodesTheme.LIGHT);
  NoCodes.getSharedInstance().showScreen("yourContextKey");

  // Reset to auto (follow system appearance)
  NoCodes.getSharedInstance().setTheme(NoCodesTheme.AUTO);
  ```
</CodeGroup>

### Screen customization

Use the screen customization delegate to customize the screen opening animation. For example, to enable or disable the animation (*iOS only*), specify the type of opening: push/popover (*iOS only*)/full screen. You can also pass a `statusBarHidden` flag that determines whether to show or hide the status bar when displaying the screen (*iOS only*).

For example:

<CodeGroup>
  ```swift Swift theme={null}
  func presentationConfigurationForScreen(contextKey: String) -> NoCodesPresentationConfiguration {
    return NoCodesPresentationConfiguration(animated: true, presentationStyle: .push)
  }
  ```

  ```kotlin Kotlin theme={null}
  override fun getPresentationConfigurationForScreen(contextKey: String): QScreenPresentationConfig {
    return QScreenPresentationConfig(QScreenPresentationStyle.Push)
  }
  ```

  ```java Java theme={null}
  @NonNull
  @Override
  public QScreenPresentationConfig getPresentationConfigurationForScreen(@NonNull String contextKey) {
    return new QScreenPresentationConfig(QScreenPresentationStyle.Push);
  }
  ```

  ```typescript React-Native theme={null}
  // Set presentation style config before showing screen if needed
  const screenConfig = new ScreenPresentationConfig(ScreenPresentationStyle.FULL_SCREEN, true);

  NoCodes.getSharedInstance().setScreenPresentationConfig(screenConfig, 'yourContextKey');
  ```

  ```dart Flutter theme={null}
  // Set presentation style config before showing screen if needed
  final config = NoCodesPresentationConfig(
      animated: true,
      presentationStyle: NoCodesPresentationStyle.fullScreen,
  );

  NoCodes.getSharedInstance().setScreenPresentationConfig(config, contextKey: 'yourContextKey');
  ```

  ```csharp Unity theme={null}
  // Set presentation style config before showing screen if needed
  var screenConfig = new ScreenPresentationConfig(ScreenPresentationStyle.FullScreen, true);

  NoCodes.GetSharedInstance().SetScreenPresentationConfig(screenConfig, "yourContextKey");
  ```

  ```typescript Cordova theme={null}
  // Set presentation style config before showing screen if needed
  const screenConfig = new Qonversion.ScreenPresentationConfig(Qonversion.ScreenPresentationStyle.FULL_SCREEN, true);

  Qonversion.NoCodes.getSharedInstance().setScreenPresentationConfig(screenConfig, 'yourContextKey');
  ```

  ```typescript Capacitor theme={null}
  // Set presentation style config before showing screen if needed
  const screenConfig = new ScreenPresentationConfig(ScreenPresentationStyle.FULL_SCREEN, true);

  NoCodes.getSharedInstance().setScreenPresentationConfig(screenConfig, 'yourContextKey');
  ```
</CodeGroup>

### Custom loading view

By default, the SDK displays a skeleton loading view while the No-Code screen is loading. You can replace it with your own custom loading view by implementing the `noCodesCustomLoadingView()` method in the screen customization delegate.

Your custom view must conform to the `NoCodesLoadingView` protocol (iOS) or implement the `NoCodesLoadingView` interface (Android). The SDK calls `startAnimating()` when the loading begins and `stopAnimating()` when the screen content is ready.

<CodeGroup>
  ```swift Swift theme={null}
  // Conform to NoCodesLoadingView
  class MyLoadingView: UIView, NoCodesLoadingView {
    func startAnimating() {
      // Start your loading animation
    }

    func stopAnimating() {
      // Stop your loading animation
    }
  }

  // Return it from the screen customization delegate
  func noCodesCustomLoadingView() -> NoCodesLoadingView? {
    return MyLoadingView(frame: .zero)
  }
  ```

  ```kotlin Kotlin theme={null}
  // Implement NoCodesLoadingView
  class MyLoadingView(context: Context) : FrameLayout(context), NoCodesLoadingView {
    override fun startAnimating() {
      // Start your loading animation
    }

    override fun stopAnimating() {
      // Stop your loading animation
    }
  }

  // Return it from the screen customization delegate
  override fun noCodesCustomLoadingView(): View? {
    return MyLoadingView(context)
  }
  ```

  ```java Java theme={null}
  // Implement NoCodesLoadingView
  public class MyLoadingView extends FrameLayout implements NoCodesLoadingView {
    @Override
    public void startAnimating() {
      // Start your loading animation
    }

    @Override
    public void stopAnimating() {
      // Stop your loading animation
    }
  }

  // Return it from the screen customization delegate
  @Nullable
  @Override
  public View noCodesCustomLoadingView() {
    return new MyLoadingView(context);
  }
  ```
</CodeGroup>

<Info>
  If `noCodesCustomLoadingView()` returns `nil` / `null`, the default skeleton loading view will be used.
</Info>

***

[Screens Preloading](screens-preloading)

[Success and Failure Actions](success-failure-actions)
