Camera & Image Capture
Capture photos and videos using the device camera or pick files from the gallery, using standard HTML file inputs.
Access: Standard HTML — no SDK method required.
For a practical guide to capturing images — see Capture Images.
The starti.app container supports the standard HTML file input for capturing images and videos. When the user taps a file input with the capture attribute, the native camera opens directly. Without capture, a chooser appears that lets the user pick from the gallery or take a new photo/video.
This works because the native container (Android and iOS) intercepts the webview's file chooser request and presents the appropriate native UI — no special SDK call is needed.
Capture an image
Use a standard <input type="file"> with accept="image/*" and the capture attribute:
<!-- Opens the camera directly -->
<input type="file" accept="image/*" capture="environment" />
<!-- Opens a chooser: gallery or camera -->
<input type="file" accept="image/*" />The capture attribute values:
| Value | Camera |
|---|---|
"user" | Front-facing camera |
"environment" | Rear-facing camera (default) |
JavaScript example
function captureImage() {
return new Promise((resolve) => {
const input = document.createElement("input");
input.type = "file";
input.accept = "image/*";
input.capture = "environment";
input.addEventListener("change", () => {
const file = input.files?.[0];
if (file) {
resolve(file);
}
});
input.click();
});
}
// Usage
const imageFile = await captureImage();
console.log("Captured:", imageFile.name, imageFile.size);
// Display the captured image
const url = URL.createObjectURL(imageFile);
document.getElementById("preview").src = url;Capture a video
<!-- Opens the video camera directly -->
<input type="file" accept="video/*" capture="environment" />
<!-- Opens a chooser: gallery or video camera -->
<input type="file" accept="video/*" />Accept multiple file types
<!-- Image or video, with chooser -->
<input type="file" accept="image/*,video/*" />
<!-- Multiple files -->
<input type="file" accept="image/*" multiple />Upload the captured file
async function captureAndUpload() {
const input = document.createElement("input");
input.type = "file";
input.accept = "image/*";
input.capture = "environment";
const file = await new Promise((resolve) => {
input.addEventListener("change", () => resolve(input.files?.[0]));
input.click();
});
if (!file) return;
const formData = new FormData();
formData.append("photo", file);
const response = await fetch("/api/upload", {
method: "POST",
body: formData,
});
console.log("Upload status:", response.status);
}Camera permissions
Camera access requires user permission. The native container handles the permission prompt automatically when the user interacts with a file input that needs the camera. On iOS (15+), the webview grants media capture permission automatically.
If you also use the QR Scanner, the camera permission requested there applies to file inputs as well — and vice versa.
Platform notes
| Behavior | Android | iOS |
|---|---|---|
capture attribute | Opens camera directly | Opens camera directly |
No capture attribute | Shows chooser (gallery + camera) | Shows chooser (gallery + camera) |
| Full-resolution photos | Yes | Yes |
| Multiple file selection | Yes | Yes |
This approach uses standard web APIs, so it also works when your page is opened in a regular mobile browser — not just inside the starti.app container.
See also
Biometrics
Authenticate users with device biometrics (Face ID, Touch ID, fingerprint) and securely store credentials or arbitrary data in the device keychain.
External Purchase
Manage Apple's External Purchase Custom Link entitlement (StoreKit external purchase API). This module lets you check eligibility, retrieve purchase tokens, display the mandatory Apple disclosure notice, and redirect the user to an external purchase page.