What's New in Flutter SDK 2.1
Flutter SDK 2.1 was tagged on 14 October 2026, about two hours after Flutter SDK 1.2. There is no 2.0 tag: 2.1.0 is the release after 1.2.0. Together they are the largest change since Flutter SDK 1.1. The board gets a new look, and the four defects that the 1.1 notes listed as still open are fixed. This post covers both tags, because 1.2.0 contains a source break of its own.
The short version
- New look:
FeedbackListdraws Showcase cards by default, with a search field and a Sort & Filter sheet.listStyle: FeedbackListStyle.classickeeps the 1.x list. - Fixed: the SDK creates a user id when you do not pass one, removing a vote works, posting a comment works, and the email typed into the form reaches FeedbackKit.
- Fixed in 1.2: the Team badge on comments renders, and a request with a status this build does not know is dropped from the list instead of showing as Pending.
- Breaking: Dart 3.6 and Flutter 3.27 are now the minimums,
Comment.feedbackIdis nullable, andRegisterUserRequestno longer has anidgetter. - Install: 2.1 is a git dependency on the
2.1.0tag. pub.dev still holds 1.0.0 and 1.0.1.
Installing 2.1
flutter pub add feedbackkit_flutter still installs 1.0.1, and a ^2.1.0 constraint does not resolve from pub.dev. Depend on the tag in the SDK's repository:
dependencies:
feedbackkit_flutter:
git:
url: https://github.com/Swiftly-Developed/SwiftlyFeedbackKit-Flutter-SDK.git
ref: 2.1.0
Your app needs Dart 3.6 and Flutter 3.27 or later. Earlier versions of the SDK asked for Dart 3.0 and Flutter 3.10.
The Showcase list
Each request is a Material 3 card: a status line with its own glyph, the title, two lines of the description, the category and comment count in the footer, and a vote pill tinted with your theme's primaryColor. Above the cards sit a search field and a Sort & Filter button. The button opens a bottom sheet with four sort orders (Votes, Newest, Oldest and Comments) and Status and Category filters. Active filters show as chips with a Clear button, and a filter that matches nothing shows No Matching Requests with Clear Filters.
Search, sort and filters run on the device over the requests already loaded, so changing them does not reload the list. Search matches the title and the description, ignoring case and accents. Cards keep their place while someone votes, and a failed vote rolls back and shows a snackbar. The list remembers the reader's sort between launches, but never the filters, so nobody comes back to a list that is quietly narrowed.
The cards follow the host app's ColorScheme, including dynamic colour and dark theme, mirror for right-to-left languages, scale text up to 2.0, and give every control a 48dp touch target and a screen-reader label. Inside a CupertinoApp, the list brings its own Material 3 theme and opens the sheet as a Cupertino modal popup.
To keep the 1.x look, set the style once on the provider, or on one list:
FeedbackKitProvider(
apiKey: const String.fromEnvironment('FEEDBACKKIT_API_KEY'),
listStyle: FeedbackListStyle.classic,
child: const MaterialApp(home: IdeasScreen()),
)
Driving the list from your own app bar
FeedbackListController holds the search text, the sort and the two filters. Create one in your widget's state, dispose it with the state, and share it between the list and a FeedbackSortFilterButton:
Scaffold(
appBar: AppBar(
title: const Text('Trailmate ideas'),
actions: [FeedbackSortFilterButton(controller: _controller)],
),
body: FeedbackList(
controller: _controller,
showToolbar: false,
onFeedbackTap: _openRequest,
),
)
A list that is given a controller does not persist the sort; that is left to the owner. Showcase also takes showStatusBadge, showCategoryBadge, showCommentCount, showVoteCount, allowUndoVote, showStatusFilter and showCategoryFilter. The Classic list ignores them.
The fixes
Each of these was present in pub.dev 1.0.1 and in every tag through 1.2.0.
- A user id from the start. When the provider gets no
userId, the SDK creates one in the formlocal_plus a UUID, stores it, and reuses it on the next launch. An id you pass now wins over a stored one and replaces it. The list waits until the id is ready, so the opening load already knows which requests the person voted for. - Removing a vote works. The user id now travels in the request body, where the server reads it.
- Posting a comment works. The comment carries the user id the server requires.
- The form's email reaches FeedbackKit. It is sent under the key the server reads, so the person who filed a request can be emailed when its status changes. The mailing-list opt-in from 1.1 now records the choice too, on projects with an email-list integration switched on, a Pro feature.
FeedbackItem.userEmailreads the address back. - The status-change opt-in on votes.
votes.vote()takesnotifyStatusChangeand anemail, sent under the keys the server reads. The oldnotifyOnStatusChangestill compiles, with a deprecation warning. - Server errors keep their message. A detailed error response used to surface as a generic
NetworkError. It now becomes the matching error class, carrying the server's message andcode, plus a newfield. - The cards speak the reader's language. The comment count and age on
FeedbackCardnow come from the catalog, Arabic lays out right to left, and the vote, retry, submit and opt-in controls are announced as buttons and checkboxes.
Also new
feedback.list()andcomments.list()read every page when you leavepageout, andcomments.list()gainedpageandperPage.RegisterUserRequesttakesuserIdand an optionalmrr, the two fields the server reads.- A 429 now raises
RateLimitError, a subclass ofFeedbackKitError, withretryAfterSecondswhen the server sends it. The SDK does not retry for you. FeedbackKitStorageis exported and can be passed to the provider asstorage.
Breaking changes and how to migrate
In 1.2.0, under a minor version number
Comment.feedbackId is String?. The server never sends that key on a comment, so in 1.1 it always decoded to an empty string. It is now null, and code that reads it as a String no longer compiles. Use the id of the request you loaded the comments for:
// Flutter SDK 1.1
final String parent = comment.feedbackId;
// Flutter SDK 1.2 and later: the request you loaded the comments for
final String parent = feedback.id;
Unknown statuses and categories throw. FeedbackStatus.fromJson and FeedbackCategory.fromJson used to turn a token they did not know into pending or other. They now throw UnknownEnumValueException, which the package exports. feedback.list() drops those rows and keeps the rest in order. If you call fromJson yourself, catch the exception.
In 2.1.0
- Dart 3.6 and Flutter 3.27. Raise the
environmentin yourpubspec.yamlif it is lower. RegisterUserRequest.idis gone. ReaduserIdinstead. Theid:constructor argument still compiles, deprecated, and is sent asuser_id.emailandnamealso still compile, deprecated, and are no longer sent, because the server ignores them.- The default list changed. Without
listStyle, your users see Showcase cards on the next build. - A plain-HTTP
baseUrlthrows. The client refuses to send the API key over cleartext and throws anArgumentError, except for a loopback address such aslocalhost, for a local server. - Stricter event tracking.
events.track()throws aValidationErrorwhen there is no user id, the name is empty, or a property value is not a string, number or boolean. Numbers and booleans are sent as strings. - Error messages changed. Errors now carry the server's own message where they used to carry a placeholder. Branch on the class or
code, not on the text.
Calling setUserId before a vote is no longer needed. Voting, removing a vote and tracking an event with no id at all are refused before any request is sent, which the generated id makes rare.
How FeedbackKit fits in
With the email now reaching FeedbackKit, someone who files from your Flutter app hears back when your team moves their request along. Here is how that looks in FeedbackKit, with sample data from a fictional hiking app:
Telling the people who asked
FeedbackKitApp
Status Update
Trailmate
Offline mapsTestFlight → Completed
Your feedback in Trailmate has a status update.
Offline maps
TestFlightCompleted
Upgrading
- Point
pubspec.yamlatref: 2.1.0, raise the Dart and Flutter minimums, and runflutter pub get. - Fix the compile errors:
Comment.feedbackIdandRegisterUserRequest.id. - Choose Showcase or Classic. Look at Showcase in dark theme, at large text sizes and in Arabic before you ship.
- If you set a placeholder user id to get round the 1.x defects, you can drop it and let the SDK create one. If your app has its own accounts, keep passing your id.
- Remove any workarounds for removing votes, posting comments or the form's email.
The notes for earlier versions are in Flutter SDK 1.0 and Flutter SDK 1.1, and the Flutter SDK 1.0 tutorial covers apps on the pub.dev build. The current Flutter tutorial is the place to start a new integration, and the reference is in the Flutter SDK docs.
Every plan includes the Flutter SDK. Start free and put the new board in your next build.