Geolocation
Read the device's position once or subscribe to continuous updates - typed coordinates, accuracy metadata and strongly-typed errors instead of raw callbacks.
@inject Bit.Butil.Geolocation geolocationMDN reference
GeolocationException with Code == GeolocationErrorCode.PermissionDenied
- always wrap calls in a try/catch.
Returns true when the runtime exposes navigator.geolocation. During prerender/SSR the check returns false rather than throwing, so defer it to OnAfterRenderAsync.
@inject Bit.Butil.Geolocation geolocation
var supported = await geolocation.IsSupported();One-shot read of the device position. GeolocationOptions maps to the browser's PositionOptions: EnableHighAccuracy trades power for precision, Timeout caps how long the device may take (milliseconds), and MaximumAge allows a cached fix up to the given age.
try
{
var pos = await geolocation.GetCurrentPosition(new GeolocationOptions
{
EnableHighAccuracy = true,
Timeout = 10_000,
MaximumAge = 0,
});
var lat = pos.Coords.Latitude;
var lng = pos.Coords.Longitude;
var accuracy = pos.Coords.Accuracy; // meters
}
catch (GeolocationException ex)
{
// ex.Code: PermissionDenied, PositionUnavailable, Timeout or Unknown
}Subscribes to continuous position updates. Watch returns a Guid you pass to ClearWatch to stop; the position handler runs on the Blazor sync context, so updating component state from it is safe.
var watchId = await geolocation.Watch(
onPosition: pos => { /* fires on every movement */ },
onError: ex => { /* GeolocationException */ });
// later:
await geolocation.ClearWatch(watchId);SubscribeWatch is the same as Watch but returns a ButilSubscription, so a component can hold one field and dispose it in DisposeAsync - no Guid bookkeeping. ClearAllWatches stops every watch this Geolocation instance has started.
private ButilSubscription? _sub;
_sub = await geolocation.SubscribeWatch(pos => { /* ... */ });
// stop this one:
await _sub.DisposeAsync();
// or stop everything started by this instance:
await geolocation.ClearAllWatches();Timeout defaults to long.MaxValue - the call
waits indefinitely for a fix. Set an explicit timeout when a slow GPS lock should fail fast.
API reference
ValueTask<bool> IsSupported()Task<GeolocationPosition> GetCurrentPosition(GeolocationOptions? options = null)Task<Guid> Watch(Action<GeolocationPosition>? onPosition, Action<GeolocationException>? onError = null, GeolocationOptions? options = null)ValueTask ClearWatch(Guid id)Task<ButilSubscription> SubscribeWatch(Action<GeolocationPosition>? onPosition, Action<GeolocationException>? onError = null, GeolocationOptions? options = null)ValueTask ClearAllWatches()ValueTask DisposeAsync()void InvokePosition(Guid id, GeolocationPosition position)void InvokeError(Guid id, int code, string message)bool EnableHighAccuracy { get; set; }long MaximumAge { get; set; }long Timeout { get; set; }