Follow

WebSDK - How to Manage the Camera?

How to initiate the Camera?

Before you start: Please note that ideally, the created Camera object should be a single instance that you reuse across your app. Otherwise, you might experience some resource-related issues as the camera requires explicit access to the hardware of the device. 

 

First, you need to create a Camera object and select the desired camera (in this case, the default one). Please make sure to create it as a global object: 

let camera: Camera;
...
camera = Camera.default;

We also suggest applying the relevant camera settings for the particular capture mode you're using, e.g.: 

const cameraSettings = BarcodeCapture.recommendedCameraSettings;
await camera.applySettings(cameraSettings);

The next step is to set the camera on the created DataCaptureContext

await context.setFrameSource(camera);

 

Note: In order to avoid issues when the user switched the camera (e.g. using the camera switcher) and started it lager, you can access the currently used camera via context.frameSource instead of the created camera object, which is no longer the selected one. If you prefer to use the default approach, we'd suggest to make sure you refer to the currently selected camera by listening when a camera changes:

context.addListener({
didChangeFrameSource: (context: DataCaptureContext, frameSource: FrameSource | null) => {
currentCamera = frameSource;
}
})

 

How to start the Camera?

Once you're ready to use the scanner, e.g. when the scanner component loads or when users click on the Scan button, please make sure to turn it on. You can read more about it under the How to manage the Camera lifecycle section below. 

await camera.switchToDesiredState(FrameSourceState.On);

Note: The camera is started asynchronously and will take some time to completely turn on. Therefore, you should await it before proceeding with the next step. 

In case your app syntax doesn't support the await operator, you can use the then() method to await the returned Promise: 

camera.switchToDesiredState(FrameSourceState.On)
.then(() => {
return barcodeCapture.setEnabled(true);
})
.then(() => {
// Optional: Code to run after barcodeCapture is enabled
})
.catch(error => {
console.error('Error:', error);
});

 

How to stop/pause the Camera?

You can either turn off the camera completely or put it in a standby state, depending on your scanning workflow. 

 

When Should I Use the Off vs. Standby State in a Scandit Workflow?

Scandit’s FrameSourceState allows you to manage the camera lifecycle efficiently. Choosing between Off and Standby depends on the performance needs and battery usage of your app.

 

Use Off When:

  • You no longer need the camera and want to fully release it.

  • The scanning session is finished (e.g., user navigates away from the scanning screen).

  • You want to reduce battery usage and free system resources.

  • Your app needs to switch to another camera (e.g., from rear to front).

Example: After a successful checkout scan, you move to a confirmation screen — switching to Off will release the camera entirely.

 

Use Standby When:

  • You want to pause scanning temporarily without fully turning off the camera.

  • The user might return to scanning shortly (e.g., switching tabs or showing a modal).

  • You need a faster resume time compared to Off.

Example: The user opens a product details modal — switching to Standby keeps the camera session warm so scanning can resume instantly when the modal is closed.

State Camera Access Resume Time Battery Use Use Case
Off Released Slow Low End of session, screen change
Standby Reserved Fast Medium Temporary UI interruptions

 

How to manage the Camera lifecycle? 

Managing the Scandit camera properly is a key to building efficient, battery-friendly, and responsive scanning workflows. Your app’s navigation and lifecycle events (e.g. screen transitions, tab switches, or backgrounding) should drive the camera’s state changes.

 

General Guideline by App State:

App State Action Camera State
Scanning screen is visible and active Start or resume scanning On
User temporarily leaves scanning screen (modal, tab switch) Pause scanning Standby
User navigates away from scanning screen completely Release camera Off
App is backgrounded Release camera Off
App returns to foreground and scanning screen is visible Resume scanning On or Standby depending on context

 

General Best Practices

  • Keep the camera in On only when scanning is needed and the UI is active.

  • Use Standby for short UI interruptions to avoid unnecessary warm-up time.

  • Always switch to Off when the scanning screen is no longer visible or app is backgrounded.

  • Pair camera state changes with UI navigation lifecycle for clean and predictable behaviour.

 

How to hook the Camera into Navigation and Framework Lifecycle? 

React

Hook Purpose
useEffect Handle mount/unmount to fully turn camera on/off
useFocusEffect Handle navigation focus/blur to pause/resume scanning gracefully
useEffect(() => {
// Set camera to On when component mounts
camera.switchToDesiredState(FrameSourceState.On);

// Cleanup: turn camera Off when component unmounts
return () => {
camera.switchToDesiredState(FrameSourceState.Off);
};
}, []);

// Focus: handle tab or screen focus in navigation
useFocusEffect(
useCallback(() => {
// Screen is focused (coming into view) – resume scanning
camera.switchToDesiredState(FrameSourceState.On);

return () => {
// Screen is blurred (e.g., tab switch, modal opens) – pause scanning
camera.switchToDesiredState(FrameSourceState.Standby);
};
}, [])
);

 

Angular

In Angular, you typically manage lifecycle with ngOnInit, ngOnDestroy, and route/navigation events.

ngOnInit(): void {
// Turn on camera when component is initialized
camera.switchToDesiredState(FrameSourceState.On);

// Optional: Handle navigation away from this component
this.navigationSub = this.router.events.subscribe(event => {
if (event instanceof NavigationStart) {
camera.switchToDesiredState(FrameSourceState.Off);
}
});
}

ngOnDestroy(): void {
// Turn off camera on component destroy
camera.switchToDesiredState(FrameSourceState.Off);

if (this.navigationSub) {
this.navigationSub.unsubscribe();
}
}

 

Vue

In Vue 2 or Vue 3, use mounted(), beforeDestroy() (Vue 2) or onMounted(), onUnmounted() (Vue 3 with Composition API).

 

Vue 2 / Options API:

mounted() {
camera.switchToDesiredState(FrameSourceState.On);
},

beforeDestroy() {
camera.switchToDesiredState(FrameSourceState.Off);
},

methods: {
onModalOpen() {
camera.switchToDesiredState(FrameSourceState.Standby);
},
onModalClose() {
camera.switchToDesiredState(FrameSourceState.On);
}
}

 

Vue 3 / Composition API:

onMounted(() => {
camera.switchToDesiredState(FrameSourceState.On);
});

onUnmounted(() => {
camera.switchToDesiredState(FrameSourceState.Off);
});

 

Troubleshooting

You can find some detailed troubleshooting tips in the following article: 

WebSDK - Why am I getting a black camera screen?  

 

 

Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request