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:
- Timeout based — show the splash for a fixed duration
- Wait handler based — wait for an API call or async work before proceeding
- 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.
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:
appmaker-splash-screen-wait-handler— if registered, takes full controlappmaker-splash-screen-timeout— if registered, overrides the default timeoutsplash_screen_timeoutfrom 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 fromappmaker-splash-screen-timeoutor app settingswaitForTimeout(timeout?)— helper that returns a promise resolving after the given timeout
Wait only for API completion
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 type | Behavior |
|---|---|
| Function | Called with { timeout, waitForTimeout } context, result is processed recursively |
| Promise | Awaited before proceeding |
| Number | Used as a timeout in milliseconds |
Numeric string (e.g. "3000") | Parsed and used as a timeout |
null, undefined, or void | Falls 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
}