ExampleVersion Enforcement

Force Update

Block users on old app versions from accessing the app and direct them to the store, using Koolbase version enforcement — no new release required.

When to use force update

Breaking API changes that old clients cannot handle
Critical security vulnerabilities fixed in the new version
Database schema changes that require a new SDK version
Deprecated endpoints being removed from the API

main.dart — full implementation

lib/main.dartDart
import 'package:flutter/material.dart';
import 'package:koolbase/koolbase.dart';
import 'package:url_launcher/url_launcher.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Koolbase.init(apiKey: 'pk_live_your_key_here');

  final check = await Koolbase.version.check();

  switch (check.status) {
    case VersionStatus.forceUpdate:
      runApp(ForceUpdateApp(
        message: check.message ?? 'This version is no longer supported. Please update to continue.',
        storeUrl: check.storeUrl,
      ));

    case VersionStatus.softUpdate:
      runApp(MyApp(showUpdateBanner: true, bannerMessage: check.message));

    case VersionStatus.upToDate:
      runApp(const MyApp());
  }
}

Force update screen

lib/screens/force_update_screen.dartDart
class ForceUpdateApp extends StatelessWidget {
  final String message;
  final String? storeUrl;

  const ForceUpdateApp({required this.message, this.storeUrl, super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.white,
        body: SafeArea(
          child: Padding(
            padding: const EdgeInsets.all(32),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Icon(Icons.system_update_alt, size: 80, color: Colors.blue),
                const SizedBox(height: 32),
                const Text(
                  'Update Required',
                  style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
                  textAlign: TextAlign.center,
                ),
                const SizedBox(height: 16),
                Text(
                  message,
                  style: const TextStyle(fontSize: 16, color: Colors.grey),
                  textAlign: TextAlign.center,
                ),
                const SizedBox(height: 40),
                if (storeUrl != null)
                  SizedBox(
                    width: double.infinity,
                    child: ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        padding: const EdgeInsets.symmetric(vertical: 16),
                      ),
                      onPressed: () => launchUrl(
                        Uri.parse(storeUrl!),
                        mode: LaunchMode.externalApplication,
                      ),
                      child: const Text('Update Now', style: TextStyle(fontSize: 16)),
                    ),
                  ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Soft update banner

lib/widgets/update_banner.dartDart
class UpdateBanner extends StatefulWidget {
  final String? message;
  const UpdateBanner({this.message, super.key});

  @override
  State<UpdateBanner> createState() => _UpdateBannerState();
}

class _UpdateBannerState extends State<UpdateBanner> {
  bool _dismissed = false;

  @override
  Widget build(BuildContext context) {
    if (_dismissed) return const SizedBox.shrink();

    return Container(
      color: Colors.blue.shade50,
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
      child: Row(
        children: [
          const Icon(Icons.info_outline, color: Colors.blue, size: 18),
          const SizedBox(width: 8),
          Expanded(
            child: Text(
              widget.message ?? 'A new version is available.',
              style: const TextStyle(fontSize: 13),
            ),
          ),
          TextButton(
            onPressed: () => launchUrl(Uri.parse(storeUrl)),
            child: const Text('Update'),
          ),
          IconButton(
            onPressed: () => setState(() => _dismissed = true),
            icon: const Icon(Icons.close, size: 16),
          ),
        ],
      ),
    );
  }
}

Set the version policy before shipping

Configure the version policy in your dashboard before shipping the new version that users need to upgrade to. Set min_version to the new version number and status to force_update only after the new version is live in the stores.