HotUpdater.wrap()
HotUpdater.wrap
checks for updates at the entry point, and if there is a bundle to update, it downloads the bundle and applies the update strategy.
Usage
Use the source
option in HotUpdater.wrap
to specify the update server URL, then wrap the App entry point.
Since it uses fetch, if you need to pass headers along with it, you can use the requestHeaders
option to pass headers.
import { HotUpdater, getUpdateSource } from "@hot-updater/react-native";
import { View, Text } from "react-native";
function App() {
return (
<View>
<Text>Hello World</Text>
</View>
);
}
export default HotUpdater.wrap({
source: getUpdateSource("<your-update-server-url>", {
updateStrategy: "fingerprint", // or "appVersion"
}),
// If you need to send request headers, you can use the `requestHeaders` option.
requestHeaders: {
"Authorization": "Bearer <your-access-token>",
},
})(App);
UnderstandinggetUpdateSource
The getUpdateSource
function is used to construct the final URL for checking for updates. It takes a baseUrl
as its first argument and an options object as its second argument. The updateStrategy
property within the options object determines the final structure of the request URL.
Example Final Endpoint Structures:
Depending on the updateStrategy
value, getUpdateSource
generates URLs like the following:
- For
updateStrategy: 'appVersion'
: GET {baseUrl}/app-version/:platform/:appVersion/:channel/:minBundleId/:bundleId
- For
updateStrategy: 'fingerprint'
: GET {baseUrl}/fingerprint/:platform/:fingerprintHash/:channel/:minBundleId/:bundleId
For example, if you provide https://your-update-server.com/api/update-check
as the baseUrl
, getUpdateSource
will append the correct path and parameters to the URL depending on whether updateStrategy
is 'appVersion'
or 'fingerprint'
.
Fallback Component
During an update check, access to the entry point is temporarily blocked while communicating with the server.
- If the update is force update, the entry point remains blocked, and the progress updates as the bundle downloads.
- If not force update, the entry point is only blocked during the update check.
Without a fallbackComponent
, the bundle downloads without blocking the screen.
fallbackComponent
Props:
progress
: Download progress (e.g., for a progress bar).
status
: Update state:
CHECK_FOR_UPDATE
: Checking for updates.
UPDATING
: Downloading the new bundle.
Using these props, you can ensure a smooth UI transition.
It is also recommended to include a splash image for a better user experience.
import { HotUpdater, getUpdateSource } from "@hot-updater/react-native";
import { View, Text, Modal } from "react-native";
function App() {
return (
<View>
<Text>Hello World</Text>
</View>
);
}
export default HotUpdater.wrap({
source: getUpdateSource("<your-update-server-url>", {
updateStrategy: "fingerprint", // or "appVersion"
}),
fallbackComponent: ({ progress, status, message }) => (
<View
style={{
flex: 1,
padding: 20,
borderRadius: 10,
justifyContent: "center",
alignItems: "center",
backgroundColor: "rgba(0, 0, 0, 0.5)",
}}
>
{/* You can put a splash image here. */}
<Text style={{ color: "white", fontSize: 20, fontWeight: "bold" }}>
{status === "UPDATING" ? "Updating..." : "Checking for Update..."}
</Text>
{message && (
<Text style={{ color: "white", fontSize: 20, fontWeight: "bold" }}>
{message}
</Text>
)}
{progress > 0 ? (
<Text style={{ color: "white", fontSize: 20, fontWeight: "bold" }}>
{Math.round(progress * 100)}%
</Text>
) : null}
</View>
),
})(App);
reloadOnForceUpdate
When a force update bundle is downloaded, the app will automatically reload. If false
, shouldForceUpdate
will be returned as true
in onUpdateProcessCompleted
but the app won't reload. default is true
.
reloadOnForceUpdate
istrue
When a force update exists, the app will automatically reload.
import { HotUpdater, getUpdateSource } from "@hot-updater/react-native";
import { View, Text } from "react-native";
function App() {
return (
<View>
<Text>Hello World</Text>
</View>
);
}
export default HotUpdater.wrap({
source: getUpdateSource("<your-update-server-url>", {
updateStrategy: "fingerprint", // or "appVersion"
}),
// If you need to send request headers, you can use the `requestHeaders` option.
requestHeaders: {
"Authorization": "Bearer <your-access-token>",
},
reloadOnForceUpdate: true, // Automatically reload the app on force updates
})(App);
reloadOnForceUpdate
isfalse
When a force update exists, the app will not reload. shouldForceUpdate
will be returned as true
in onUpdateProcessCompleted
.
import { HotUpdater, getUpdateSource } from "@hot-updater/react-native";
import { View, Text } from "react-native";
function App() {
return (
<View>
<Text>Hello World</Text>
</View>
);
}
export default HotUpdater.wrap({
source: getUpdateSource("<your-update-server-url>", {
updateStrategy: "fingerprint", // or "appVersion"
}),
// If you need to send request headers, you can use the `requestHeaders` option.
requestHeaders: {
"Authorization": "Bearer <your-access-token>",
},
reloadOnForceUpdate: false, // The app won't reload on force updates
onUpdateProcessCompleted: ({ status, shouldForceUpdate, id, message }) => {
console.log("Bundle updated:", status, shouldForceUpdate, id, message);
if (shouldForceUpdate) {
HotUpdater.reload();
}
},
})(App);
onUpdateProcessCompleted
The onUpdateProcessCompleted
option allows you to perform additional actions after the update process is completed.
Callback Arguments
Property | Type | Description |
---|
status | "ROLLBACK" | "UPDATE" | "UP_TO_DATE" | The status of the update process |
shouldForceUpdate | boolean | Whether the update process is forced |
id | string | The ID of the bundle to update |
message | string | The message of the update process |
import { HotUpdater, getUpdateSource } from "@hot-updater/react-native";
import { View, Text } from "react-native";
function App() {
return (
<View>
<Text>Hello World</Text>
</View>
);
}
export default HotUpdater.wrap({
source: getUpdateSource("<your-update-server-url>", {
updateStrategy: "fingerprint", // or "appVersion"
}),
// If you need to send request headers, you can use the `requestHeaders` option.
requestHeaders: {
"Authorization": "Bearer <your-access-token>",
},
onUpdateProcessCompleted: ({ isBundleUpdated, message }) => {
// if isBundleUpdated is true, `HotUpdater.reload()` or restart the app to apply the new bundle
// if isBundleUpdated is false, the app is up to date
console.log("Bundle updated:", isBundleUpdated, message);
},
// If you need to show the progress while downloading the new bundle, you can use the `onProgress` option.
onProgress: ({ progress }) => {
console.log("Bundle downloading progress:", progress);
},
})(App);
Update Strategy
Update Type | When Applied | How to Enable |
---|
Default | Downloads the update bundle in the background and applies it when the user restarts the app. | Default setting |
Force Update | Downloads the update bundle and applies it immediately. | Use the --force-update flag or console. |
Custom source Function
You can pass an async function to the source option for full control over how update info is fetched.
export default HotUpdater.wrap({
source: async () => {
const res = await fetch("https://your.api/update-info");
return (await res.json()) as AppUpdateInfo | null;
},
// ... other options
});