You can read GET parameters from a URL in a Flutter web app using Uri.base.queryParameters
for direct access or by integrating parameter parsing into your routing logic, such as with onGenerateRoute
.
The Uri.base.queryParameters
property provides a map of the key-value pairs from the current URL’s query string.
Direct Access with Uri.base.queryParameters
This is the simplest way to get a URL parameter anywhere in your application. It gives you a Map<String, String>
of all the query parameters in the current browser URL.
For a URL like https://yourapp.com/#/?id=123&name=flutter
, you can access the parameters as follows.
Code Example
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
@Override
Widget build(BuildContext context) {
// Get the full query parameters map
final queryParams = Uri.base.queryParameters;
// Access a specific parameter by its key
final String? userId = queryParams['id'];
final String? userName = queryParams['name'];
final String? referrer = queryParams['ref']; // Will be null if not present
return Scaffold(
appBar: AppBar(
title: const Text('URL GET Parameters'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('User ID: ${userId ?? 'Not Found'}'),
Text('User Name: ${userName ?? 'Not Found'}'),
Text('Referrer: ${referrer ?? 'Not Found'}'),
],
),
),
);
}
}
DartKey Points
- Easy and Direct: This method is great for quickly reading a value without complex routing setup.
- Returns Strings: All values in the
queryParameters
map are strings. You’ll need to parse them if you expect other types (e.g.,int.parse()
). - Null Safety: Always handle the case where a parameter might not exist in the URL. Accessing a key that isn’t present will return
null
.
Integrating with Flutter’s Navigator
For more robust applications, it’s a best practice to handle URL parameters as part of your routing logic. This allows you to show different pages or states based on the parameters. You can achieve this using the onGenerateRoute
property of MaterialApp
.
This approach is useful for routing to a specific product or user profile page, like https://yourapp.com/#/product?id=456
.
Code Example
Here’s how you can set up onGenerateRoute
to parse parameters for a specific route.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
// The magic happens here!
onGenerateRoute: (settings) {
// Handle the '/' home route
if (settings.name == '/') {
return MaterialPageRoute(builder: (context) => const HomePage());
}
// Handle the '/product' route
final uri = Uri.parse(settings.name!);
if (uri.path == '/product') {
final productId = uri.queryParameters['id'];
return MaterialPageRoute(
builder: (context) => ProductPage(productId: productId),
);
}
// If no route matches, show a default page
return MaterialPageRoute(builder: (context) => const UnknownPage());
},
);
}
}
class ProductPage extends StatelessWidget {
final String? productId;
const ProductPage({super.key, this.productId});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Product Details')),
body: Center(
child: Text('Displaying product with ID: ${productId ?? 'None'}'),
),
);
}
}
// Define HomePage and UnknownPage widgets...
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) => Scaffold(body: const Center(child: Text('Home Page')));
}
class UnknownPage extends StatelessWidget {
const UnknownPage({super.key});
@override
Widget build(BuildContext context) => Scaffold(body: const Center(child: Text('404: Page Not Found')));
}
DartKey Points
- Structured & Scalable: This method is cleaner for apps with multiple routes that depend on URL parameters.
- Centralized Logic: Keeps all your routing and parameter-handling logic in one place.
- Recommended for Apps: While direct access is easy, this is the recommended pattern for building full-featured web applications. Modern routing packages like GoRouter build on this principle and make it even easier.