Skip to content

Commit af834ee

Browse files
authored
Make the App's title optional on web (#152003)
Title (in web) results in updating the [title element][1] which is a global property. This is problematic in embedded and multiview modes as title should be managed by host apps. This PR makes the title optional, hence if not provided it won't result in the website title being updated.
1 parent b7997cb commit af834ee

File tree

5 files changed

+29
-11
lines changed

5 files changed

+29
-11
lines changed

packages/flutter/lib/src/cupertino/app.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ class CupertinoApp extends StatefulWidget {
166166
this.onNavigationNotification,
167167
List<NavigatorObserver> this.navigatorObservers = const <NavigatorObserver>[],
168168
this.builder,
169-
this.title = '',
169+
this.title,
170170
this.onGenerateTitle,
171171
this.color,
172172
this.locale,
@@ -207,7 +207,7 @@ class CupertinoApp extends StatefulWidget {
207207
this.routerConfig,
208208
this.theme,
209209
this.builder,
210-
this.title = '',
210+
this.title,
211211
this.onGenerateTitle,
212212
this.onNavigationNotification,
213213
this.color,
@@ -303,7 +303,7 @@ class CupertinoApp extends StatefulWidget {
303303
/// {@macro flutter.widgets.widgetsApp.title}
304304
///
305305
/// This value is passed unmodified to [WidgetsApp.title].
306-
final String title;
306+
final String? title;
307307

308308
/// {@macro flutter.widgets.widgetsApp.onGenerateTitle}
309309
///

packages/flutter/lib/src/material/app.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ class MaterialApp extends StatefulWidget {
275275
this.routerConfig,
276276
this.backButtonDispatcher,
277277
this.builder,
278-
this.title = '',
278+
this.title,
279279
this.onGenerateTitle,
280280
this.onNavigationNotification,
281281
this.color,
@@ -386,7 +386,7 @@ class MaterialApp extends StatefulWidget {
386386
/// {@macro flutter.widgets.widgetsApp.title}
387387
///
388388
/// This value is passed unmodified to [WidgetsApp.title].
389-
final String title;
389+
final String? title;
390390

391391
/// {@macro flutter.widgets.widgetsApp.onGenerateTitle}
392392
///

packages/flutter/lib/src/widgets/app.dart

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ class WidgetsApp extends StatefulWidget {
328328
this.home,
329329
Map<String, WidgetBuilder> this.routes = const <String, WidgetBuilder>{},
330330
this.builder,
331-
this.title = '',
331+
this.title,
332332
this.onGenerateTitle,
333333
this.textStyle,
334334
required this.color,
@@ -425,7 +425,7 @@ class WidgetsApp extends StatefulWidget {
425425
this.routerConfig,
426426
this.backButtonDispatcher,
427427
this.builder,
428-
this.title = '',
428+
this.title,
429429
this.onGenerateTitle,
430430
this.onNavigationNotification,
431431
this.textStyle,
@@ -828,7 +828,7 @@ class WidgetsApp extends StatefulWidget {
828828
///
829829
/// To provide a localized title instead, use [onGenerateTitle].
830830
/// {@endtemplate}
831-
final String title;
831+
final String? title;
832832

833833
/// {@template flutter.widgets.widgetsApp.onGenerateTitle}
834834
/// If non-null this callback function is called to produce the app's
@@ -1771,7 +1771,7 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
17711771
return true;
17721772
}());
17731773

1774-
final Widget title;
1774+
final Widget? title;
17751775
if (widget.onGenerateTitle != null) {
17761776
title = Builder(
17771777
// This Builder exists to provide a context below the Localizations widget.
@@ -1786,9 +1786,14 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
17861786
);
17871787
},
17881788
);
1789+
} else if (widget.title == null && kIsWeb) {
1790+
// Updating the <title /> element in the DOM is problematic in embedded
1791+
// and multiview modes as title should be managed by host apps.
1792+
// Refer to https://github.com/flutter/flutter/pull/152003 for more info.
1793+
title = null;
17891794
} else {
17901795
title = Title(
1791-
title: widget.title,
1796+
title: widget.title ?? '',
17921797
color: widget.color.withOpacity(1.0),
17931798
child: result,
17941799
);
@@ -1823,7 +1828,7 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
18231828
child: Localizations(
18241829
locale: appLocale,
18251830
delegates: _localizationsDelegates.toList(),
1826-
child: title,
1831+
child: title ?? result,
18271832
),
18281833
),
18291834
),

packages/flutter/test/cupertino/app_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ void main() {
7070
);
7171
await tester.pumpWidget(const CupertinoApp(
7272
theme: CupertinoThemeData(brightness: Brightness.light),
73+
title: '',
7374
color: dynamicColor,
7475
home: Placeholder(),
7576
));
@@ -79,6 +80,7 @@ void main() {
7980
await tester.pumpWidget(const CupertinoApp(
8081
theme: CupertinoThemeData(brightness: Brightness.dark),
8182
color: dynamicColor,
83+
title: '',
8284
home: Placeholder(),
8385
));
8486

packages/flutter/test/widgets/app_test.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,17 @@ void main() {
153153
expect(checked, isTrue);
154154
}, variant: KeySimulatorTransitModeVariant.all());
155155

156+
testWidgets('Title is not created if title is not passed and kIsweb', (WidgetTester tester) async {
157+
await tester.pumpWidget(
158+
WidgetsApp(
159+
color: const Color(0xFF123456),
160+
builder: (BuildContext context, Widget? child) => Container(),
161+
),
162+
);
163+
164+
expect(find.byType(Title), kIsWeb ? findsNothing : findsOneWidget);
165+
});
166+
156167
group('error control test', () {
157168
Future<void> expectFlutterError({
158169
required GlobalKey<NavigatorState> key,

0 commit comments

Comments
 (0)