Answer
Pass a dictionary to GoToAsync and receive it via query properties. Decorate the target page or view model with [QueryProperty] (or implement IQueryAttributable) so MAUI injects the values. Objects can be passed in-memory via the dictionary; primitives can also go in the query string.
await Shell.Current.GoToAsync("details",
new Dictionary<string, object> { ["Item"] = selected });
[QueryProperty(nameof(Item), "Item")]
public partial class DetailsPage : ContentPage
{ public Product Item { get; set; } }Real-world example A catalog passes the selected product object straight to the details page's view model without re-fetching it from the server.