# Preference Center Let users manage their notification preferences and subscription lists with Preference Center. # Get started with Preference Center on Flutter > Preference Center allows users to opt in and out of subscription lists configured via the Airship dashboard. > **Important:** Airship Preference Centers are widgets that can be embedded in a page in an app or website. Please verify with your legal team that your full Preference Center page, including any web page for email Preference Centers, is compliant with local privacy regulations. Preference Center provides a pre-built UI for users to manage their subscription preferences. Learn more in the [Preference Center user guide](https://www.airship.com/docs/guides/messaging/features/preference-centers/). ## Display a Preference Center Display a Preference Center with a single method call: ```dart Airship.preferenceCenter.display("preference-center-id"); ``` To build a custom Preference Center UI, see [Embedding the Preference Center](https://www.airship.com/docs/developer/sdk-integration/flutter/preference-center/embedding/). # Embed the Preference Center > Create custom Preference Center UIs by fetching the config and building your own subscription management interface. This guide covers creating custom Preference Center UIs for Flutter applications. Unlike the default Preference Center, you'll build your own UI from scratch using the Preference Center configuration and subscription list APIs. ## Override Default Display Behavior To use a custom Preference Center instead of the default UI, disable auto-launch for the specific Preference Center ID and handle display events: ```dart // Disable the OOTB UI for this Preference Center Airship.preferenceCenter.setAutoLaunchDefaultPreferenceCenter( "preference-center-id", false ); // Add a listener to handle display events StreamSubscription? subscription; subscription = Airship.preferenceCenter.onDisplay.listen((event) { final preferenceCenterId = event.preferenceCenterId; // Navigate to your custom preference center UI navigateToCustomPreferenceCenter(preferenceCenterId); }); ``` ## Fetching Preference Center Config The Preference Center config contains all the information needed to build your UI, including subscription lists, sections, and display settings. ```dart PreferenceCenterConfig config = await Airship.preferenceCenter.getConfig("preference-center-id"); ``` > **Note:** The config might not be available immediately on first app start. Implement exponential backoff if automatically retrying, or provide a UI for users to manually retry. ## Building Your Custom UI You'll need to: 1. **Fetch the config** to get the list of subscription lists and their current state 2. **Build your UI** using the config data (sections, subscription lists, display settings) 3. **Update subscription lists** when users make changes using the [Subscription List APIs](https://www.airship.com/docs/developer/sdk-integration/flutter/audience/subscription-lists/) ### Example Implementation ```dart import 'package:flutter/material.dart'; import 'package:airship_flutter/airship_flutter.dart'; class CustomPreferenceCenterScreen extends StatefulWidget { final String preferenceCenterId; const CustomPreferenceCenterScreen({ Key? key, required this.preferenceCenterId, }) : super(key: key); @override _CustomPreferenceCenterScreenState createState() => _CustomPreferenceCenterScreenState(); } class _CustomPreferenceCenterScreenState extends State { PreferenceCenterConfig? _config; bool _loading = true; Map _subscriptions = {}; @override void initState() { super.initState(); _loadConfig(); } Future _loadConfig() async { try { final config = await Airship.preferenceCenter.getConfig( widget.preferenceCenterId, ); // Load current subscription status final currentSubs = await Airship.contact.subscriptionLists; final subsMap = {}; for (var section in config.sections) { for (var item in section.items) { if (item.subscriptionId != null) { subsMap[item.subscriptionId!] = currentSubs.contains(item.subscriptionId); } } } setState(() { _config = config; _subscriptions = subsMap; _loading = false; }); } catch (error) { print('Failed to load config: $error'); setState(() { _loading = false; }); } } Future _toggleSubscription(String listId, bool subscribe) async { try { if (subscribe) { await Airship.contact.editSubscriptionLists() .subscribe(listId) .apply(); } else { await Airship.contact.editSubscriptionLists() .unsubscribe(listId) .apply(); } setState(() { _subscriptions[listId] = subscribe; }); } catch (error) { print('Failed to update subscription: $error'); } } @override Widget build(BuildContext context) { if (_loading) { return Scaffold( appBar: AppBar(title: Text('Loading...')), body: Center(child: CircularProgressIndicator()), ); } if (_config == null) { return Scaffold( appBar: AppBar(title: Text('Error')), body: Center( child: Text('Failed to load Preference Center'), ), ); } return Scaffold( appBar: AppBar( title: Text(_config!.display?.name ?? 'Preferences'), ), body: ListView.builder( itemCount: _config!.sections.length, itemBuilder: (context, sectionIndex) { final section = _config!.sections[sectionIndex]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (section.display?.name != null) Padding( padding: EdgeInsets.all(16), child: Text( section.display!.name!, style: Theme.of(context).textTheme.titleLarge, ), ), ...section.items.map((item) { final subscriptionId = item.subscriptionId; if (subscriptionId == null) return SizedBox.shrink(); return SwitchListTile( title: Text(item.display?.name ?? ''), subtitle: item.display?.description != null ? Text(item.display!.description!) : null, value: _subscriptions[subscriptionId] ?? false, onChanged: (value) { _toggleSubscription(subscriptionId, value); }, ); }).toList(), Divider(), ], ); }, ), ); } } ``` > **Important:** Preference Center configuration is currently limited to subscription lists only. Use the [Subscription List APIs](https://www.airship.com/docs/developer/sdk-integration/flutter/audience/subscription-lists/) to manage user subscriptions.