diff --git a/lib/app.dart b/lib/app.dart
new file mode 100644
index 0000000000000000000000000000000000000000..ccdef33ac22d7d8582b9320bf670d969d3833f10
--- /dev/null
+++ b/lib/app.dart
@@ -0,0 +1,105 @@
+import 'package:article_flutter_riverpod/example.dart';
+import 'package:article_flutter_riverpod/screens/example_group_screen.dart';
+import 'package:article_flutter_riverpod/screens/example_screen.dart';
+import 'package:flutter/material.dart';
+import 'package:go_router/go_router.dart';
+
+final GlobalKey<NavigatorState> _rootNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'root');
+final GlobalKey<NavigatorState> _shellNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'shell');
+
+class App extends StatelessWidget {
+  App(
+    this.groups, {
+    Key? key,
+  })  : router = buildRouter(groups),
+        super(key: key);
+
+  final List<ExampleGroup> groups;
+  final GoRouter router;
+
+  @override
+  Widget build(BuildContext context) {
+    return MaterialApp.router(
+      title: 'Flutter par la pratique',
+      theme: ThemeData(
+        primarySwatch: Colors.blue,
+      ),
+      routeInformationProvider: router.routeInformationProvider,
+      routerDelegate: router.routerDelegate,
+      routeInformationParser: router.routeInformationParser,
+    );
+  }
+
+  static GoRouter buildRouter(List<ExampleGroup> groups) {
+    return GoRouter(
+      navigatorKey: _rootNavigatorKey,
+      initialLocation: groups[0].path,
+      routes: [
+        ShellRoute(
+          navigatorKey: _shellNavigatorKey,
+          builder: (_, __, child) => ScaffoldWithNavBar(groups, child: child),
+          routes: [
+            for (ExampleGroup group in groups) //
+              GoRoute(
+                path: group.path,
+                builder: (_, __) => ExampleGroupScreen(group),
+                routes: [
+                  for (Example example in group.examples) //
+                    GoRoute(
+                      path: example.path,
+                      builder: (_, __) => ExampleScreen(example),
+                    ),
+                ],
+              ),
+          ],
+        )
+      ],
+    );
+  }
+}
+
+class ScaffoldWithNavBar extends StatelessWidget {
+  const ScaffoldWithNavBar(
+    this.groups, {
+    required this.child,
+    Key? key,
+  }) : super(key: key);
+
+  final List<ExampleGroup> groups;
+  final Widget child;
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      body: child,
+      bottomNavigationBar: BottomNavigationBar(
+        items: [
+          for (ExampleGroup group in groups) //
+            BottomNavigationBarItem(
+              icon: Icon(group.icon),
+              label: group.title,
+            ),
+        ],
+        currentIndex: _calculateSelectedIndex(context),
+        onTap: (index) => _onItemTapped(index, context),
+      ),
+    );
+  }
+
+  int _calculateSelectedIndex(BuildContext context) {
+    final GoRouter route = GoRouter.of(context);
+    final String location = route.location;
+
+    for (var i = 0; i < groups.length; i++) {
+      if (location.startsWith(groups[i].path)) {
+        return i;
+      }
+    }
+
+    return 0;
+  }
+
+  void _onItemTapped(int index, BuildContext context) {
+    context.go(groups[index].path);
+  }
+}
diff --git a/lib/example.dart b/lib/example.dart
index 0e6c382f59da3c13b8b45348bb0cfb1be2ebd950..bff1680ce10baa1826baa85d3c07b400ac06eb69 100644
--- a/lib/example.dart
+++ b/lib/example.dart
@@ -3,10 +3,14 @@ import 'package:flutter/material.dart';
 class ExampleGroup {
   const ExampleGroup({
     required this.title,
+    required this.icon,
+    required this.path,
     required this.examples,
   });
 
   final String title;
+  final IconData icon;
+  final String path;
   final List<Example> examples;
 }
 
@@ -25,28 +29,3 @@ class Example {
   final WidgetBuilder builder;
   final bool isScrollable;
 }
-
-class ExampleContainer extends StatelessWidget {
-  const ExampleContainer(
-    this.example, {
-    Key? key,
-  }) : super(key: key);
-
-  final Example example;
-
-  @override
-  Widget build(BuildContext context) {
-    final child = example.builder(context);
-
-    return Scaffold(
-      appBar: AppBar(
-        title: Text(example.title),
-      ),
-      body: Center(
-        child: example.isScrollable
-            ? SingleChildScrollView(child: child) //
-            : child,
-      ),
-    );
-  }
-}
diff --git a/lib/main.dart b/lib/main.dart
index 68b8034592bb91285379efd4b1cbea77f555dfe7..438938f7de20f7392c00ab31344aa69cb4a87495 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,3 +1,4 @@
+import 'package:article_flutter_riverpod/app.dart';
 import 'package:article_flutter_riverpod/article_02/consumer_example.dart';
 import 'package:article_flutter_riverpod/article_02/parent_example.dart';
 import 'package:article_flutter_riverpod/article_02/stateful_example.dart';
@@ -12,12 +13,12 @@ import 'package:article_flutter_riverpod/presentation/07_overrides_example.dart'
 import 'package:article_flutter_riverpod/presentation/08_future_provider_example.dart' as future_provider_example;
 import 'package:article_flutter_riverpod/presentation/09_async_value_example.dart' as async_value_example;
 import 'package:flutter/material.dart';
-import 'package:go_router/go_router.dart';
-import 'package:sticky_headers/sticky_headers.dart';
 
-final examples = [
+final _groups = [
   ExampleGroup(
     title: 'Article 01',
+    icon: Icons.filter_1,
+    path: '/article_01',
     examples: [
       Example(
         title: 'Consumer',
@@ -47,6 +48,8 @@ final examples = [
   ),
   ExampleGroup(
     title: 'Presentation',
+    icon: Icons.screenshot_monitor,
+    path: '/presentation',
     examples: [
       Example(
         title: 'Introduction',
@@ -109,106 +112,5 @@ final examples = [
 ];
 
 void main() {
-  runApp(ArticleApp());
-}
-
-class ArticleApp extends StatelessWidget {
-  ArticleApp({Key? key}) : super(key: key);
-
-  final _router = GoRouter(routes: [
-    GoRoute(
-      path: '/',
-      builder: (_, __) => const HomePage(),
-      routes: [
-        for (ExampleGroup exampleTitle in examples) //
-          for (Example example in exampleTitle.examples) //
-            GoRoute(
-              path: example.path,
-              builder: (_, __) => ExampleContainer(example),
-            )
-      ],
-    ),
-  ]);
-
-  @override
-  Widget build(BuildContext context) {
-    return MaterialApp.router(
-      routeInformationProvider: _router.routeInformationProvider,
-      routeInformationParser: _router.routeInformationParser,
-      routerDelegate: _router.routerDelegate,
-      title: 'Flutter par la pratique',
-      theme: ThemeData(
-        primarySwatch: Colors.blue,
-      ),
-    );
-  }
-}
-
-class HomePage extends StatelessWidget {
-  const HomePage({Key? key}) : super(key: key);
-
-  @override
-  Widget build(BuildContext context) {
-    return Scaffold(
-      appBar: AppBar(
-        title: const Text('Flutter par la pratique'),
-      ),
-      body: ListView.builder(
-        itemBuilder: (_, index) => ExampleGroupListItem(examples[index]),
-        itemCount: examples.length,
-      ),
-    );
-  }
-}
-
-class ExampleGroupListItem extends StatelessWidget {
-  const ExampleGroupListItem(this.exampleGroup, {Key? key}) : super(key: key);
-
-  final ExampleGroup exampleGroup;
-
-  @override
-  Widget build(BuildContext context) {
-    return StickyHeader(
-      header: Container(
-        height: 50,
-        color: Colors.white,
-        alignment: Alignment.centerLeft,
-        padding: const EdgeInsets.symmetric(horizontal: 16),
-        child: Text(
-          exampleGroup.title,
-          overflow: TextOverflow.ellipsis,
-          style: Theme.of(context).textTheme.subtitle2,
-        ),
-      ),
-      content: Column(
-        mainAxisSize: MainAxisSize.min,
-        children: [
-          for (Example example in exampleGroup.examples) //
-            ExampleListItem(example)
-        ],
-      ),
-    );
-  }
-}
-
-class ExampleListItem extends StatelessWidget {
-  const ExampleListItem(this.example, {Key? key}) : super(key: key);
-
-  final Example example;
-
-  @override
-  Widget build(BuildContext context) {
-    return ListTile(
-      leading: Icon(
-        example.icon,
-        color: Theme.of(context).primaryColor,
-      ),
-      title: Text(
-        example.title,
-        overflow: TextOverflow.ellipsis,
-      ),
-      trailing: const Icon(Icons.chevron_right),
-      onTap: () => context.push('/${example.path}'),
-    );
-  }
+  runApp(App(_groups));
 }
diff --git a/lib/presentation/05_state_provider_example.dart b/lib/presentation/05_state_provider_example.dart
index efd9cf706acac320786e1c7cdea8fc20cd52a111..725bcfcb42663ce08be05ef9cb2b4b994518c9f1 100644
--- a/lib/presentation/05_state_provider_example.dart
+++ b/lib/presentation/05_state_provider_example.dart
@@ -52,7 +52,9 @@ class _TodoListState extends ConsumerState<TodoList> {
 
   void _onCheckedChanged(Todo todo, bool? value) {
     final updatedTodo = todo.copyWith(checked: value != null && value);
-    ref.read(todosProvider.notifier).state = ref.read(todosProvider.notifier).state.copyWithTodo(updatedTodo);
+
+    final todos = ref.read(todosProvider);
+    ref.read(todosProvider.notifier).state = todos.copyWithTodo(updatedTodo);
   }
 }
 
diff --git a/lib/presentation/09_async_value_example.dart b/lib/presentation/09_async_value_example.dart
index 3254c29da375ff9281f3241f677a405a7a0ab32f..88600b753de9644dc850fa5877263116c7f7edd7 100644
--- a/lib/presentation/09_async_value_example.dart
+++ b/lib/presentation/09_async_value_example.dart
@@ -1,3 +1,4 @@
+import 'package:article_flutter_riverpod/presentation/01_introduction_example.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 
@@ -160,12 +161,19 @@ class TodosStateNotifier extends StateNotifier<AsyncValue<List<Todo>>> {
   final TodosRepository todosRepository;
 
   void load() async {
-    state = await AsyncValue.guard(() => todosRepository.getTodos());
+    final todos = await AsyncValue.guard(() => todosRepository.getTodos());
+    if (mounted) {
+      state = todos;
+    }
   }
 
   void updateTodo(Todo updatedTodo) async {
     state = const AsyncValue.loading();
-    state = await AsyncValue.guard(() => todosRepository.updateTodos(updatedTodo));
+
+    final todos = await AsyncValue.guard(() => todosRepository.updateTodos(updatedTodo));
+    if (mounted) {
+      state = todos;
+    }
   }
 }
 
diff --git a/lib/screens/example_group_screen.dart b/lib/screens/example_group_screen.dart
new file mode 100644
index 0000000000000000000000000000000000000000..c65917d8022f7765ecf06b292e81a2077ea59f97
--- /dev/null
+++ b/lib/screens/example_group_screen.dart
@@ -0,0 +1,59 @@
+import 'package:article_flutter_riverpod/example.dart';
+import 'package:flutter/material.dart';
+import 'package:go_router/go_router.dart';
+
+class ExampleGroupScreen extends StatelessWidget {
+  const ExampleGroupScreen(
+    this.group, {
+    Key? key,
+  }) : super(key: key);
+
+  final ExampleGroup group;
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: Text(group.title),
+      ),
+      body: ListView.builder(
+        itemBuilder: (_, index) => ExampleListItem(
+          group,
+          group.examples[index],
+        ),
+        itemCount: group.examples.length,
+      ),
+    );
+  }
+}
+
+class ExampleListItem extends StatelessWidget {
+  const ExampleListItem(
+    this.group,
+    this.example, {
+    Key? key,
+  }) : super(key: key);
+
+  final ExampleGroup group;
+  final Example example;
+
+  @override
+  Widget build(BuildContext context) {
+    return ListTile(
+      leading: Icon(
+        example.icon,
+        color: Theme.of(context).primaryColor,
+      ),
+      title: Text(
+        example.title,
+        overflow: TextOverflow.ellipsis,
+      ),
+      trailing: const Icon(Icons.chevron_right),
+      onTap: () => _onItemTapped(context, example),
+    );
+  }
+
+  void _onItemTapped(BuildContext context, Example example) {
+    context.go("${group.path}/${example.path}");
+  }
+}
diff --git a/lib/screens/example_screen.dart b/lib/screens/example_screen.dart
new file mode 100644
index 0000000000000000000000000000000000000000..1c73a96812733c077988e7724a8358b8b7f4c125
--- /dev/null
+++ b/lib/screens/example_screen.dart
@@ -0,0 +1,27 @@
+import 'package:article_flutter_riverpod/example.dart';
+import 'package:flutter/material.dart';
+
+class ExampleScreen extends StatelessWidget {
+  const ExampleScreen(
+    this.example, {
+    Key? key,
+  }) : super(key: key);
+
+  final Example example;
+
+  @override
+  Widget build(BuildContext context) {
+    final child = example.builder(context);
+
+    return Scaffold(
+      appBar: AppBar(
+        title: Text(example.title),
+      ),
+      body: Center(
+        child: example.isScrollable
+            ? SingleChildScrollView(child: child) //
+            : child,
+      ),
+    );
+  }
+}
diff --git a/lib/toto.md b/lib/toto.md
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7c0e3fd76e05e99cc1f5f289afb64b45d8aa2aaf 100644
--- a/lib/toto.md
+++ b/lib/toto.md
@@ -0,0 +1,177 @@
+```dart
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+
+class TodoExample extends StatelessWidget {
+  const TodoExample({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return const ProviderScope(
+      child: TodoList(),
+    );
+  }
+}
+
+class TodoList extends ConsumerStatefulWidget {
+  const TodoList({Key? key}) : super(key: key);
+
+  @override
+  ConsumerState<TodoList> createState() => _TodoListState();
+}
+
+class _TodoListState extends ConsumerState<TodoList> {
+  bool _isUncheckedFilter = false;
+
+  @override
+  Widget build(BuildContext context) {
+    final todos = ref.watch(todosProvider.select((tds) => tds.whereTodos(_isUncheckedFilter)));
+
+    return Column(
+      children: [
+        TodoListFilter(
+          filter: _isUncheckedFilter,
+          onFilterChanged: _onFilterChanged,
+        ),
+        const Divider(height: 1),
+        Expanded(
+          child: ListView.builder(
+            itemBuilder: (_, index) =>
+                TodoListItem(
+                  todos[index],
+                  onCheckedChanged: (value) => _onCheckedChanged(todos[index], value),
+                ),
+            itemCount: todos.length,
+          ),
+        ),
+      ],
+    );
+  }
+
+  void _onFilterChanged(bool value) {
+    setState(() => _isUncheckedFilter = value);
+  }
+
+  void _onCheckedChanged(Todo todo, bool? value) {
+    final updatedTodo = todo.copyWith(checked: value != null && value);
+
+    final todos = ref.read(todosProvider.notifier).state;
+    ref.read(todosProvider.notifier).state = todos.copyWithTodo(updatedTodo);
+  }
+}
+
+class TodoListFilter extends StatelessWidget {
+  const TodoListFilter({
+    Key? key,
+    required this.filter,
+    required this.onFilterChanged,
+  }) : super(key: key);
+
+  final bool filter;
+  final ValueChanged<bool> onFilterChanged;
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: const EdgeInsets.symmetric(horizontal: 16),
+      child: Row(
+        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+        children: [
+          const Text("Unchecked"),
+          Switch(
+            value: filter,
+            onChanged: onFilterChanged,
+          ),
+        ],
+      ),
+    );
+  }
+}
+
+class TodoListItem extends StatelessWidget {
+  const TodoListItem(this.todo, {
+    Key? key,
+    this.onCheckedChanged,
+  }) : super(key: key);
+
+  final Todo todo;
+  final ValueChanged<bool?>? onCheckedChanged;
+
+  @override
+  Widget build(BuildContext context) {
+    return CheckboxListTile(
+      value: todo.checked,
+      onChanged: onCheckedChanged,
+      title: Text(
+        todo.title,
+        overflow: TextOverflow.ellipsis,
+      ),
+      controlAffinity: ListTileControlAffinity.leading,
+    );
+  }
+}
+
+final todosProvider = StateProvider<List<Todo>>((ref) => todos);
+
+const todos = [
+  Todo(
+    id: 0,
+    title: 'Unit test passed',
+    checked: true,
+  ),
+  Todo(
+    id: 1,
+    title: 'Code reviewed',
+    checked: true,
+  ),
+  Todo(
+    id: 2,
+    title: 'Acceptance criteria for each issue met',
+  ),
+  Todo(
+    id: 3,
+    title: 'Functional tests passed',
+  ),
+  Todo(
+    id: 4,
+    title: 'Non-functional requirements met',
+  ),
+  Todo(
+    id: 5,
+    title: 'Product owner accepts the User Story',
+  ),
+];
+
+class Todo {
+  const Todo({
+    required this.id,
+    required this.title,
+    this.checked = false,
+  });
+
+  final int id;
+  final String title;
+  final bool checked;
+
+  Todo copyWith({
+    int? id,
+    String? title,
+    bool? checked,
+  }) {
+    return Todo(
+      id: id ?? this.id,
+      title: title ?? this.title,
+      checked: checked ?? this.checked,
+    );
+  }
+}
+
+extension TodoListExtension on List<Todo> {
+  List<Todo> whereTodos(bool isUnchecked) => //
+  where((todo) => !isUnchecked || !todo.checked).toList();
+
+  List<Todo> copyWithTodo(Todo updatedTodo) => //
+  [for (Todo todo in this) todo.id == updatedTodo.id ? updatedTodo : todo];
+}
+
+```
\ No newline at end of file
diff --git a/pubspec.lock b/pubspec.lock
index 2e4e015be1eda5adacb447482a40a661b01dfe9a..dbdf552e195ad1ccf803eb43c122d1073c41ec24 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -92,7 +92,7 @@ packages:
       name: go_router
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "4.3.0"
+    version: "4.5.0"
   js:
     dependency: transitive
     description:
@@ -175,13 +175,6 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "0.7.2+1"
-  sticky_headers:
-    dependency: "direct main"
-    description:
-      name: sticky_headers
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "0.3.0+2"
   stream_channel:
     dependency: transitive
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 3437f3bd69f7b90b41159989c85691004e3499f6..3cfd5b0b6789adf0781ce1b2bebf2a6c47cab44f 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -35,8 +35,7 @@ dependencies:
   # Use with the CupertinoIcons class for iOS style icons.
   cupertino_icons: ^1.0.2
   flutter_riverpod: ^2.0.0-dev.9
-  go_router: ^4.3.0
-  sticky_headers: ^0.3.0
+  go_router: ^4.5.0
 
 dev_dependencies:
   flutter_test: