SDK Integration- Flutter

Learn how to integrate our SDK in your existing app

SDK Integration - Flutter

Learn how to integrate Digia UI SDK in your existing Flutter application to enable server-driven UI capabilities.

Platform Support

Currently supported platforms for integration:

Platform
Status

Flutter

✅ Available

Android

🔄 Coming Soon

iOS

🔄 Coming Soon

Web

🔄 Coming Soon

Installation

Add Digia UI SDK to your project using one of the following methods:

Method 1: Flutter CLI

flutter pub add digia_ui

Method 2: Manual pubspec.yaml

Update your pubspec.yaml file:

dependencies:
  digia_ui: ^1.0.0

Then run:

flutter pub get

Integration Options

Digia UI SDK offers two implementation approaches based on your app's architecture needs.

Use this approach when DigiaUI needs to be initialized before rendering the first frame. This is ideal for full Digia-powered applications.

import 'package:digia_ui/digia_ui.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  final digiaUI = await DigiaUI.initialize(
    DigiaUIOptions(
      accessKey: 'YOUR_PROJECT_ACCESS_KEY',
      flavor: Flavor.release(),
      strategy: NetworkFirstStrategy(timeoutInMs: 2000),
    ),
  );
  
  runApp(
    DigiaUIApp(
      digiaUI: digiaUI,
      builder: (context) => MaterialApp(
        home: DUIFactory().createInitialPage(),
      ),
    ),
  );
}

Option 2: Using DigiaUIAppBuilder (Advanced)

For advanced use cases where you need granular control over the initialization process. Useful when your app starts with native Flutter pages before transitioning to Digia UI screens.

import 'package:digia_ui/digia_ui.dart';

void main() {
  runApp(
    DigiaUIAppBuilder(
      options: DigiaUIOptions(
        accessKey: 'YOUR_PROJECT_ACCESS_KEY',
        flavor: Flavor.release(),
        strategy: NetworkFirstStrategy(timeoutInMs: 2000),
      ),
      builder: (context, status) {
        // Access DUIFactory only when SDK is ready
        if (status.isReady) {
          return MaterialApp(
            home: DUIFactory().createInitialPage(),
          );
        }
        
        // Show loading indicator while initializing
        if (status.isLoading) {
          return MaterialApp(
            home: Scaffold(
              body: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  CircularProgressIndicator(),
                  SizedBox(height: 16),
                  Text('Loading latest content...'),
                  if (status.hasCache)
                    TextButton(
                      onPressed: () => status.useCachedVersion(),
                      child: Text('Use Offline Version'),
                    ),
                ],
              ),
            ),
          );
        }
        
        // Handle initialization errors
        return MaterialApp(
          home: Scaffold(
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Icon(Icons.error_outline, size: 48),
                  SizedBox(height: 16),
                  Text('Failed to load content'),
                  Text('Error: ${status.error}'),
                  if (status.hasCache)
                    ElevatedButton(
                      onPressed: () => status.useCachedVersion(),
                      child: Text('Use Cached Version'),
                    ),
                ],
              ),
            ),
          ),
        );
      },
    ),
  );
}

Configuration Parameters

DigiaUIOptions

The main configuration object for initializing the SDK.

accessKey

  • Type: String

  • Required: true

  • Description: Your Project Access Key from Digia Studio. This identifies your specific project and enables access to your UI configurations.

flavor

  • Type: Flavor

  • Required: true

  • Description: Controls how the app loads and manages configurations.

Available Flavors:

  • Flavor.debug() - Always pulls the latest config changes from the dashboard. Use during development or testing.

  • Flavor.staging() - Pulls the latest config from the staging environment.

  • Flavor.release() - Uses production-ready configurations with caching optimizations.

  • Flavor.versioned(version) - Fetches a specific version of the configuration.

Usage Patterns

Full App Mode

Build your entire application in Digia Studio and render it completely through the SDK:

MaterialApp(
  home: DUIFactory().createInitialPage(),
  onGenerateRoute: (settings) {
    return DUIFactory().createPageRoute(
      settings.name!,
      settings.arguments as Map<String, dynamic>?,
    );
  },
)

Hybrid Mode

Mix native Flutter screens with Digia UI pages for incremental migration:

// Navigate to a Digia UI page from native Flutter
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (_) => DUIFactory().createPage('checkout_page', {
      'cartId': cartId,
      'userId': userId,
    }),
  ),
);

Pages are complete, full-screen UI definitions with lifecycle hooks. Display name for pages given on Digia Studio are converted into snake case when you want to open them from code eg

First Page -> first_page
// Create a page with arguments
Widget checkoutPage = DUIFactory().createPage(
  'checkout_page',
  {
    'cartId': '12345',
    'totalAmount': 99.99,
  },
);

// Navigate to a page
Navigator.push(
  context,
  DUIFactory().createPageRoute('product_details', {
    'productId': product.id,
  }),
);

Creating Components

Components are reusable UI elements that can be embedded within native Flutter widgets.

Display name for components given on Digia Studio are converted into snake case when you want to open them from code eg

First Component -> first_component
class ProductListPage extends StatelessWidget {
  final List<Product> products;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Products')),
      body: ListView.builder(
        itemCount: products.length,
        itemBuilder: (context, index) {
          final product = products[index];
          return DUIFactory().createComponent(
            'product_list_item',
            {
              'id': product.id,
              'title': product.title,
              'price': product.price,
              'imageUrl': product.imageUrl,
              'onTap': () => _navigateToProduct(context, product),
              'onAddToCart': () => _addToCart(product),
            },
          );
        },
      ),
    );
  }
}

State Management

Digia UI provides a comprehensive state management system with four levels of state hierarchy, enabling seamless integration between native Flutter code and server-driven UI components.

State Hierarchy Overview

  1. Global State (App State) - Available everywhere in the app

  2. Page State - Available within the current page and its components

  3. Component State - Available within the specific component instance

  4. Local State (State Container) - Available within the State Container widget subtree

Read the State Management docs to understand more about them.

Global State (App State)

Global state is shared across the entire app and provides bidirectional communication between your native Flutter code and Digia UI pages, enabling seamless integration and real-time updates.

Key Features

  • Bidirectional Access - Read and write from both native Flutter code and Digia UI

  • Stream-Based - All state changes are broadcast through streams for reactive programming

  • Real-time Updates - UI automatically updates when state changes from any source

  • Persistence - Can optionally persist between app sessions

Setting State from Native Code

// In your native Flutter code
class CartManager {
  void addToCart(Product product) {
    // Update your business logic
    cart.add(product);

    // Sync with Digia UI - these changes will be immediately reflected in all Digia UI pages
    DUIAppState().setValue('cartCount', cart.length);
    DUIAppState().setValue('cartTotal', cart.totalAmount);
    DUIAppState().setValue('cartItems', cart.items.map((item) => item.toJson()).toList());
  }

  void updateUserProfile(User user) {
    // Update user data that Digia UI pages can access
    DUIAppState().setValue('user', {
      'id': user.id,
      'name': user.name,
      'email': user.email,
      'avatar': user.avatarUrl,
      'preferences': user.preferences.toJson(),
    });
  }
}

Listening to State Changes in Native Code

Global state changes can be monitored through streams, enabling reactive programming patterns:

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  late StreamSubscription _stateSubscription;

  @override
  void initState() {
    super.initState();

    // Listen to all global state changes
    _stateSubscription = DUIAppState().listen('cartCount', (value) {
      _updateCartBadge(value);
    });
  }

  @override
  void dispose() {
    // Remember to cancel the subscription
    _stateSubscription.cancel();
    super.dispose();
  }

  void _updateCartBadge(int count) {
    // Update native Flutter UI elements
    setState(() {
      // Update cart badge in app bar
    });
  }
}

StreamBuilder Integration in Digia Studio

Since global state is stream-based, you can wrap any widget with StreamBuilder in Digia Studio to create reactive UI components that automatically update when state changes:

In Digia Studio Visual Editor:

  • Drag a StreamBuilder widget from the widget palette

  • Configure the stream source to listen to specific global state keys

  • Design the UI that should update when the state changes

  • Use expressions to access the stream data

Best Practices for Global State

  • Use meaningful keys - Choose descriptive names like user.profile instead of data1

  • Structure complex data - Use nested objects for related data

  • Minimize state size - Only store what's necessary for UI updates

  • Handle null values - Always provide fallbacks in expressions

  • Clean up on logout - Clear sensitive data when user logs out

  • Use streams wisely - Cancel subscriptions to prevent memory leaks

Custom Widget Registration

Read Custom Widgets to integreate your own flutter widgets that can be used on Digia pages.

Example Repository

For a complete working example, check out our starter repository: Digia Flutter Starter

Last updated