Skip to main content

How to customize your app's splashscreen

Overview

This tutorial shows you how to customize the SplashScreen component. You can control splash behavior in three ways:

  1. Timeout based — show the splash for a fixed duration
  2. Wait handler based — wait for an API call or async work before proceeding
  3. Custom component — replace the splash screen UI

All filters must be registered outside the activate function of your theme. Otherwise, the filters won't be applied before the SplashScreen is shown.

info

This flow is used only when custom splash is enabled through app-settings.enable_custom_splash.

Resolution order

When the splash screen mounts, it resolves what to wait for in this order:

  1. appmaker-splash-screen-wait-handler — if registered, takes full control
  2. appmaker-splash-screen-timeout — if registered, overrides the default timeout
  3. splash_screen_timeout from app settings — the default fallback

Timeout based splash

Use appmaker-splash-screen-timeout when you only want a fixed delay.

import { appmaker } from "@appmaker-xyz/core";

// Change the timeout. Default is from app settings (typically 500 ms).
appmaker.addFilter(
"appmaker-splash-screen-timeout",
"my-theme-name",
() => 5000 // timeout in ms
);

Wait for an API before loading the app

Use appmaker-splash-screen-wait-handler when the splash should wait for custom async work like an API call before the app loads.

The handler receives a context object with:

  • timeout — the resolved timeout from appmaker-splash-screen-timeout or app settings
  • waitForTimeout(timeout?) — helper that returns a promise resolving after the given timeout

Wait only for API completion

tip

For production use, consider adding an AbortSignal tied to the timeout value to avoid indefinite waits. See the fallback example below.

import { appmaker } from "@appmaker-xyz/core";

appmaker.addFilter(
"appmaker-splash-screen-wait-handler",
"my-theme/splash-api-wait",
() => async () => {
const response = await fetch("https://example.com/bootstrap");
await response.json();
}
);

Wait for API or fall back to timeout

import { appmaker } from "@appmaker-xyz/core";

appmaker.addFilter(
"appmaker-splash-screen-timeout",
"my-theme/splash-timeout",
() => 5000
);

appmaker.addFilter(
"appmaker-splash-screen-wait-handler",
"my-theme/splash-api-wait",
() => async ({ timeout, waitForTimeout }) => {
const controller = new AbortController();
const fallbackTimer = setTimeout(() => controller.abort(), timeout);

try {
const response = await fetch("https://example.com/bootstrap", {
signal: controller.signal,
});
await response.json();
} catch (error) {
// If the API call fails or times out, the app continues loading
return;
} finally {
clearTimeout(fallbackTimer);
}
}
);

Reuse the old timeout through the new filter

import { appmaker } from "@appmaker-xyz/core";

appmaker.addFilter(
"appmaker-splash-screen-wait-handler",
"my-theme/splash-wait-handler",
() => ({ timeout, waitForTimeout }) => waitForTimeout(timeout)
);

Supported return types

The appmaker-splash-screen-wait-handler filter can return:

Return typeBehavior
FunctionCalled with { timeout, waitForTimeout } context, result is processed recursively
PromiseAwaited before proceeding
NumberUsed as a timeout in milliseconds
Numeric string (e.g. "3000")Parsed and used as a timeout
null, undefined, or voidFalls back to the default timeout

Error handling

If the wait handler throws or rejects, the app logs the error and continues loading. The splash screen will never get stuck.

Custom splash component

Use appmaker-splash-screen-component to replace the splash screen UI.

import { appmaker } from "@appmaker-xyz/core";
import SplashScreen from "./SplashScreen";

appmaker.addFilter(
"appmaker-splash-screen-component",
"my-theme-name",
() => SplashScreen
);

function activate(theme) {
// your theme activate function codes
}

Example: Video splash screen

import React from "react";
import { View } from "react-native";
import Video from "react-native-video";

const SplashScreen = () => {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Video
source={require("./splash.mp4")} // use a local file for fast loading
shouldPlay={true}
resizeMode="cover"
style={{ width: 300, height: 600 }}
isMuted={false}
/>
</View>
);
};
export default SplashScreen;

Full example

Combining all three filters — custom timeout, async wait handler, and custom component:

import { appmaker } from "@appmaker-xyz/core";
import SplashScreen from "./SplashScreen";

// 1. Set a custom timeout (used as fallback)
appmaker.addFilter(
"appmaker-splash-screen-timeout",
"my-theme-name",
() => 5000
);

// 2. Wait for bootstrap API before loading
appmaker.addFilter(
"appmaker-splash-screen-wait-handler",
"my-theme-name",
() => async ({ timeout }) => {
const controller = new AbortController();
const fallbackTimer = setTimeout(() => controller.abort(), timeout);

try {
const response = await fetch("https://example.com/bootstrap", {
signal: controller.signal,
});
await response.json();
} catch (error) {
return;
} finally {
clearTimeout(fallbackTimer);
}
}
);

// 3. Use a custom splash component
appmaker.addFilter(
"appmaker-splash-screen-component",
"my-theme-name",
() => SplashScreen
);

function activate(theme) {
// your theme activate function codes
}